]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merged from trunk
authorheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 25 Aug 2013 14:20:31 +0000 (14:20 +0000)
committerheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 25 Aug 2013 14:20:31 +0000 (14:20 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_manifold_id@30480 0785d39b-7218-0410-832d-ea1e28bc413d

111 files changed:
deal.II/cmake/config/CMakeLists.txt
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_petsc.cmake
deal.II/cmake/configure/configure_2_trilinos.cmake
deal.II/cmake/configure/configure_boost.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_append_libraries.cmake [moved from deal.II/cmake/macros/macro_split_debug_release.cmake with 51% similarity]
deal.II/cmake/modules/FindMETIS.cmake
deal.II/cmake/modules/FindP4EST.cmake
deal.II/cmake/modules/FindTRILINOS.cmake
deal.II/doc/development/Config.sample
deal.II/doc/documentation.html
deal.II/doc/news/changes.h
deal.II/examples/step-10/doc/results.dox
deal.II/examples/step-14/step-14.cc
deal.II/examples/step-42/step-42.cc
deal.II/examples/step-51/doc/intro.dox
deal.II/examples/step-51/doc/results.dox
deal.II/examples/step-51/step-51.cc
deal.II/include/deal.II/base/data_out_base.h
deal.II/include/deal.II/base/parameter_handler.h
deal.II/include/deal.II/dofs/dof_accessor.templates.h
deal.II/include/deal.II/fe/component_mask.h
deal.II/include/deal.II/fe/fe_tools.h
deal.II/include/deal.II/fe/mapping_c1.h
deal.II/include/deal.II/fe/mapping_q.h
deal.II/include/deal.II/fe/mapping_q_eulerian.h
deal.II/include/deal.II/grid/tria.h
deal.II/include/deal.II/grid/tria_boundary.h
deal.II/include/deal.II/hp/fe_values.h
deal.II/include/deal.II/integrators/laplace.h
deal.II/include/deal.II/lac/constraint_matrix.h
deal.II/include/deal.II/lac/slepc_solver.h
deal.II/include/deal.II/meshworker/integration_info.h
deal.II/include/deal.II/meshworker/simple.h
deal.II/include/deal.II/multigrid/sparse_matrix_collection.h [new file with mode: 0644]
deal.II/include/deal.II/numerics/data_out.h
deal.II/include/deal.II/numerics/data_out_dof_data.h [new file with mode: 0644]
deal.II/include/deal.II/numerics/data_out_rotation.h
deal.II/include/deal.II/numerics/error_estimator.h
deal.II/include/deal.II/numerics/vector_tools.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/parameter_handler.cc
deal.II/source/base/partitioner.cc
deal.II/source/dofs/CMakeLists.txt
deal.II/source/dofs/dof_accessor.cc
deal.II/source/dofs/dof_accessor.inst.in
deal.II/source/dofs/dof_accessor_get.cc [new file with mode: 0644]
deal.II/source/dofs/dof_accessor_get.inst.in [new file with mode: 0644]
deal.II/source/dofs/dof_accessor_set.cc [new file with mode: 0644]
deal.II/source/dofs/dof_accessor_set.inst.in [new file with mode: 0644]
deal.II/source/dofs/dof_tools.cc
deal.II/source/dofs/dof_tools.inst.in
deal.II/source/dofs/dof_tools_constraints.cc [new file with mode: 0644]
deal.II/source/dofs/dof_tools_constraints.inst.in [new file with mode: 0644]
deal.II/source/dofs/dof_tools_sparsity.cc [new file with mode: 0644]
deal.II/source/dofs/dof_tools_sparsity.inst.in [new file with mode: 0644]
deal.II/source/fe/CMakeLists.txt
deal.II/source/fe/fe.cc
deal.II/source/fe/fe_q_base.cc
deal.II/source/fe/fe_tools.cc
deal.II/source/fe/fe_tools.inst.in
deal.II/source/fe/fe_tools_interpolate.cc [new file with mode: 0644]
deal.II/source/fe/fe_tools_interpolate.inst.in [new file with mode: 0644]
deal.II/source/fe/mapping_c1.cc
deal.II/source/fe/mapping_q.cc
deal.II/source/fe/mapping_q_eulerian.cc
deal.II/source/grid/grid_out.cc
deal.II/source/grid/tria_boundary.cc
deal.II/source/grid/tria_boundary_lib.cc
deal.II/source/lac/slepc_solver.cc
deal.II/source/numerics/CMakeLists.txt
deal.II/source/numerics/data_out.cc
deal.II/source/numerics/data_out.inst.in
deal.II/source/numerics/data_out_dof_data.cc [new file with mode: 0644]
deal.II/source/numerics/data_out_dof_data.inst.in [new file with mode: 0644]
deal.II/source/numerics/error_estimator.cc
deal.II/source/numerics/error_estimator.inst.in
deal.II/source/numerics/error_estimator_1d.cc [new file with mode: 0644]
deal.II/source/numerics/error_estimator_1d.inst.in [new file with mode: 0644]
deal.II/source/numerics/solution_transfer.cc
deal.II/source/numerics/solution_transfer.inst.in
deal.II/source/numerics/solution_transfer_inst2.cc
deal.II/source/numerics/solution_transfer_inst3.cc [new file with mode: 0644]
deal.II/source/numerics/solution_transfer_inst4.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools.inst.in [deleted file]
deal.II/source/numerics/vector_tools_boundary.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_boundary.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_constraints.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_constraints.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_integrate_difference.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_integrate_difference.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_interpolate.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_interpolate.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_mean_value.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_mean_value.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_point_value.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_point_value.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_project.cc [moved from deal.II/source/numerics/vector_tools.cc with 95% similarity]
deal.II/source/numerics/vector_tools_project.inst.in [new file with mode: 0644]
deal.II/source/numerics/vector_tools_rhs.cc [new file with mode: 0644]
deal.II/source/numerics/vector_tools_rhs.inst.in [new file with mode: 0644]

index 071ba6110bfad9f5f91bbdeda6ada12d6c7e4c5c..8cea9494f3664736db6bc15879acf442868df0a0 100644 (file)
@@ -76,8 +76,8 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
 
   SET(CONFIG_LIBRARIES_${_build}
     \${DEAL_II_PATH}/\${DEAL_II_LIBRARY_RELDIR}/${CONFIG_LIBRARY_${_build}}
-    ${DEAL_II_EXTERNAL_LIBRARIES}
     ${DEAL_II_EXTERNAL_LIBRARIES_${_build}}
+    ${DEAL_II_EXTERNAL_LIBRARIES}
     )
   LIST(APPEND CONFIG_LIBRARIES
     ${_keyword}
@@ -172,8 +172,8 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
     #
     SET(_libs)
     FOREACH(_lib
-        ${DEAL_II_EXTERNAL_LIBRARIES}
         ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
+        ${DEAL_II_EXTERNAL_LIBRARIES}
         )
       IF(_lib MATCHES "^\\s*/")
         LIST(APPEND _libs "${_lib}")
@@ -190,8 +190,8 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
     SET(_paths)
     FOREACH(_lib
         $(D)/${DEAL_II_LIBRARY_RELDIR}/${CONFIG_LIBRARY_${build}}
-        ${DEAL_II_EXTERNAL_LIBRARIES}
         ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
+        ${DEAL_II_EXTERNAL_LIBRARIES}
         )
 
       #
index 455a4944b493ac2cd0fd69eb436d4f2be5f97182..7c64e0dbe989682f520d1e3e0c17f7b7b733b256 100644 (file)
@@ -83,7 +83,7 @@ ENDMACRO()
 MACRO(FEATURE_LAPACK_CONFIGURE_EXTERNAL)
 
   ADD_FLAGS(DEAL_II_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}")
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${LAPACK_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${LAPACK_LIBRARIES})
 
   CHECK_FOR_LAPACK_FUNCTIONS()
 ENDMACRO()
index 2eb6bd3847771a695d08d83904aa1ca763d95992..51408488406939b56ec4060830c7f3dfea7f7bfd 100644 (file)
@@ -95,7 +95,7 @@ MACRO(FEATURE_MPI_CONFIGURE_EXTERNAL)
   ADD_FLAGS(CMAKE_CXX_FLAGS "${MPI_CXX_COMPILE_FLAGS}")
   ADD_FLAGS(DEAL_II_LINKER_FLAGS "${MPI_CXX_LINK_FLAGS}")
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${MPI_CXX_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${MPI_CXX_LIBRARIES})
   INCLUDE_DIRECTORIES(${MPI_CXX_INCLUDE_PATH})
 
   # The user has to know the location of the mpi headers as well:
index d43fd3ea49d29f30041d3927e594672fca95be35..e6ddef4076d247e70d8fd220ec643221459ab5a2 100644 (file)
@@ -153,7 +153,7 @@ ENDMACRO()
 MACRO(FEATURE_THREADS_CONFIGURE_EXTERNAL)
   INCLUDE_DIRECTORIES(${TBB_INCLUDE_DIR})
 
-  SPLIT_DEBUG_RELEASE(_tbb_debug _tbb_release ${TBB_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${TBB_LIBRARIES})
 
   IF(CMAKE_BUILD_TYPE MATCHES "Debug")
     IF(TBB_WITH_DEBUG_LIB)
@@ -162,12 +162,8 @@ MACRO(FEATURE_THREADS_CONFIGURE_EXTERNAL)
         )
     ENDIF()
 
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_DEBUG ${_tbb_debug})
   ENDIF()
 
-  IF(CMAKE_BUILD_TYPE MATCHES "Release")
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_RELEASE ${_tbb_release})
-  ENDIF()
 
   SETUP_THREADING()
 ENDMACRO()
@@ -200,7 +196,7 @@ MACRO(FEATURE_THREADS_CONFIGURE_BUNDLED)
   FIND_LIBRARY(dl_LIBRARY NAMES dl)
   MARK_AS_ADVANCED(dl_LIBRARY)
   IF(NOT dl_LIBRARY MATCHES "-NOTFOUND")
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${dl_LIBRARY})
+    DEAL_II_APPEND_LIBRARIES(${dl_LIBRARY})
   ENDIF()
 
   INCLUDE_DIRECTORIES(${TBB_FOLDER}/include)
index 8d83b9661d61d70fa8d1a7df3d2060186f7f0b7f..1a49a2c7c2bebd8bbfcab618e94a2e14c98d4f18 100644 (file)
@@ -38,6 +38,7 @@ MACRO(FEATURE_METIS_FIND_EXTERNAL var)
       SET(METIS_DIR "" CACHE PATH
         "An optional hint to a metis directory"
         )
+      MARK_AS_ADVANCED(CLEAR METIS_DIR)
     ENDIF()
   ENDIF()
 ENDMACRO()
index a78757796a2f85a0da8c64ce3d9a471848b2d14c..23465a2eb088e9e7b27aa94d8b366ee8823d6aef 100644 (file)
@@ -104,6 +104,7 @@ MACRO(FEATURE_PETSC_FIND_EXTERNAL var)
       SET(PETSC_ARCH "" CACHE STRING
         "An optional hint to a PETSc arch"
         )
+      MARK_AS_ADVANCED(CLEAR PETSC_DIR PETSC_ARCH)
     ENDIF()
   ENDIF()
 ENDMACRO()
@@ -115,7 +116,7 @@ MACRO(FEATURE_PETSC_CONFIGURE_EXTERNAL)
   # The user has to know the location of the petsc headers as well:
   LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${PETSC_INCLUDE_DIRS})
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${PETSC_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${PETSC_LIBRARIES})
 
   #
   # Disable a bunch of warnings when compiling with petsc:
index 3669492796fab047a6afeb9114f7110b639c31f3..ac15b3405123564435c034a5b19da41af2fbe254 100644 (file)
@@ -181,6 +181,15 @@ MACRO(FEATURE_TRILINOS_FIND_EXTERNAL var)
     ENDIF()
 
   ENDIF(TRILINOS_FOUND)
+
+  IF(NOT ${var})
+    UNSET(TRILINOS_CONFIG CACHE)
+    SET(TRILINOS_DIR "" CACHE STRING
+      "An optional hint to a Trilinos installation"
+      )
+    MARK_AS_ADVANCED(CLEAR TRILINOS_DIR)
+  ENDIF()
+
 ENDMACRO()
 
 
@@ -191,7 +200,7 @@ MACRO(FEATURE_TRILINOS_CONFIGURE_EXTERNAL)
   # The user has to know the location of the trilinos headers as well:
   LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${TRILINOS_INCLUDE_DIRS})
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${TRILINOS_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${TRILINOS_LIBRARIES})
 
   SET(DEAL_II_EXPAND_TRILINOS_VECTOR "TrilinosWrappers::Vector")
   SET(DEAL_II_EXPAND_TRILINOS_BLOCKVECTOR "TrilinosWrappers::BlockVector")
index f2071971ea5b63ced0ab9358ab0d29316ab952b3..b6ed7c3b2c825145d13c486eab977e4ed31e5900 100644 (file)
@@ -26,7 +26,7 @@
 IF(NOT FEATURE_THREADS_PROCESSED)
   MESSAGE(FATAL_ERROR "\n"
     "Internal build system error:\n"
-    "configure_boost.cmake included before configure_tbb.cmake\n\n"
+    "configure_boost.cmake included before configure_1_threads.cmake\n\n"
     )
 ENDIF()
 
@@ -38,7 +38,11 @@ SET(DEAL_II_WITH_BOOST ON # Always true. We need it :-]
 
 MACRO(FEATURE_BOOST_FIND_EXTERNAL var)
 
-  SET_IF_EMPTY(BOOST_DIR "$ENV{BOOST_DIR}")
+  IF(NOT DEFINED BOOST_DIR)
+    SET(BOOST_DIR "$ENV{BOOST_DIR}")
+  ELSE()
+    SET_IF_EMPTY(BOOST_DIR "$ENV{BOOST_DIR}")
+  ENDIF()
   IF(NOT "${BOOST_DIR}" STREQUAL "")
     SET(BOOST_ROOT "${BOOST_DIR}")
   ENDIF()
@@ -104,19 +108,8 @@ MACRO(FEATURE_BOOST_CONFIGURE_EXTERNAL)
   #
   LIST(REMOVE_ITEM Boost_LIBRARIES "pthread")
 
-  #
-  # Transform  Boost_LIBRARIES into a list of debug and release libraries
-  # without keywords:
-  #
-  SPLIT_DEBUG_RELEASE(_boost_debug _boost_release ${Boost_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${Boost_LIBRARIES})
 
-  IF (CMAKE_BUILD_TYPE MATCHES "Debug")
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_DEBUG ${_boost_debug})
-  ENDIF()
-
-  IF (CMAKE_BUILD_TYPE MATCHES "Release")
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_RELEASE ${_boost_release})
-  ENDIF()
 ENDMACRO()
 
 
index d46c23409b3a688e64d103012cd095179dcc460f..98160543019f0920f6eda9cd3b6b2be63350cd14 100644 (file)
@@ -37,6 +37,12 @@ MACRO(FEATURE_HDF5_FIND_EXTERNAL var)
         "  HDF5_WITH_MPI    = ${HDF5_WITH_MPI}\n"
         )
     ENDIF()
+
+  INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIRS})
+  LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
+  DEAL_II_APPEND_LIBRARIES(${HDF5_LIBRARIES})
+  
+
   ENDIF()
 ENDMACRO()
 
index f4a9a27446f7b43bba9ec0848dfd54b85458ab99..0739098602b54007e33dd76d6d314d46cf8be00c 100644 (file)
@@ -26,7 +26,7 @@ MACRO(FEATURE_MUMPS_CONFIGURE_EXTERNAL)
   # The user has to know the location of the MUMPS headers as well:
   LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${MUMPS_INCLUDE_DIRS})
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${MUMPS_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${MUMPS_LIBRARIES})
 ENDMACRO()
 
 CONFIGURE_FEATURE(MUMPS)
index 3773a88b12576ec6de4b7591aace8ba199ed435c..9780127bc6d157952aecec14369f96b7cd6cd7e8 100644 (file)
@@ -36,13 +36,16 @@ MACRO(FEATURE_P4EST_FIND_EXTERNAL var)
         "p4est has to be configured with MPI enabled.\n"
         )
 
-      UNSET(P4EST_LIBRARY CACHE)
+      UNSET(P4EST_LIBRARY_OPTIMIZED CACHE)
+      UNSET(P4EST_LIBRARY_DEBUG CACHE)
       UNSET(P4EST_INCLUDE_DIR CACHE)
-      UNSET(SC_LIBRARY CACHE)
+      UNSET(SC_LIBRARY_OPTIMIZED CACHE)
+      UNSET(SC_LIBRARY_DEBUG CACHE)
       UNSET(SC_INCLUDE_DIR CACHE)
       SET(P4EST_DIR "" CACHE PATH
         "An optional hint to a p4est installation/directory"
         )
+      MARK_AS_ADVANCED(CLEAR P4EST_DIR)
     ELSE()
       SET(${var} TRUE)
     ENDIF()
@@ -55,7 +58,7 @@ MACRO(FEATURE_P4EST_CONFIGURE_EXTERNAL)
   # The user has to know the location of the P4EST headers as well:
   LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${P4EST_INCLUDE_DIRS})
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${P4EST_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${P4EST_LIBRARIES})
 ENDMACRO()
 
 CONFIGURE_FEATURE(P4EST)
index c0d1b212b0b6fe3865a1147d614a9b5a7fc0a857..bf5415a0ff1deaac7af641df706736bc08b89de0 100644 (file)
@@ -50,6 +50,7 @@ MACRO(FEATURE_SLEPC_FIND_EXTERNAL var)
       SET(SLEPC_DIR "" CACHE PATH
         "An optional hint to a SLEPc directory"
         )
+      MARK_AS_ADVANCED(CLEAR SLEPC_DIR)
 
       SET(${var} FALSE)
     ENDIF()
@@ -62,7 +63,7 @@ MACRO(FEATURE_SLEPC_CONFIGURE_EXTERNAL)
   # The user has to know the location of the SLEPC headers as well:
   LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${SLEPC_INCLUDE_DIRS})
 
-  LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${SLEPC_LIBRARIES})
+  DEAL_II_APPEND_LIBRARIES(${SLEPC_LIBRARIES})
 ENDMACRO()
 
 
index 0ae79de3c0543b01f308a85d8210b13956c4f206..0ffbf4fb10481bbfaadd20c92dcd677187e1583f 100644 (file)
@@ -142,7 +142,7 @@ MACRO(FEATURE_CONFIGURE_EXTERNAL _feature)
     INCLUDE_DIRECTORIES(${${_feature}_INCLUDE_DIRS})
   ENDIF()
   IF(DEFINED ${_feature}_LIBRARIES)
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${${_feature}_LIBRARIES})
+    DEAL_II_APPEND_LIBRARIES(${${_feature}_LIBRARIES})
   ENDIF()
   IF(DEFINED ${_feature}_LINKER_FLAGS)
     ADD_FLAGS(DEAL_II_LINKER_FLAGS "${${_feature}_LINKER_FLAGS}")
similarity index 51%
rename from deal.II/cmake/macros/macro_split_debug_release.cmake
rename to deal.II/cmake/macros/macro_deal_ii_append_libraries.cmake
index dd05b98c9cc056e3c38fb9b1bc97821ed93a5245..de291d39b62d0921182025df5eab4a13286e4eba 100644 (file)
 ##
 ## ---------------------------------------------------------------------
 
-
 #
-# A small macro to split a list of libraries with debug, optimized and
-# general keywords into two lists consisting of all libraries necessary for
-# the debug and release target only. If no keyword is given "optimized" is
-# assumed.
+# A small macro to add libraries to
+#   DEAL_II_EXTERNAL_LIBRARIES
+#   DEAL_II_EXTERNAL_LIBRARIES_DEBUG
+#   DEAL_II_EXTERNAL_LIBRARIES_RELEASE
+# depending on the "optmized", "debug" or "general" keyword
 #
 # Usage:
-#     SPLIT_DEBUG_RELEASE(list_debug list_release <...list of libraries...>)
-#
+#   DEAL_II_APPEND_LIBRARIES(<list of libraries>)
 #
 
-MACRO(SPLIT_DEBUG_RELEASE _list_debug _list_release)
+MACRO(DEAL_II_APPEND_LIBRARIES)
 
-  SET(_toggle "optimized")
+  SET(_toggle "general")
   FOREACH(_tmp ${ARGN})
-    IF("${_tmp}" STREQUAL "debug" OR
-       "${_tmp}" STREQUAL "optimized" OR
-       "${_tmp}" STREQUAL "general")
+    IF( "${_tmp}" STREQUAL "debug" OR
+        "${_tmp}" STREQUAL "optimized" OR
+        "${_tmp}" STREQUAL "general" )
       SET(_toggle "${_tmp}")
     ELSE()
       IF("${_toggle}" STREQUAL "general")
-        LIST(APPEND ${_list_debug} "${_tmp}")
-        LIST(APPEND ${_list_release} "${_tmp}")
+        LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${_tmp})
       ELSEIF("${_toggle}" STREQUAL "debug")
-        LIST(APPEND ${_list_debug} "${_tmp}")
+        LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_DEBUG ${_tmp})
       ELSEIF("${_toggle}" STREQUAL "optimized")
-        LIST(APPEND ${_list_release} "${_tmp}")
+        LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_RELEASE ${_tmp})
       ENDIF()
     ENDIF()
   ENDFOREACH()
 
-  IF("${${_list_debug}}" STREQUAL "")
-    SET(${_list_debug} ${${_list_release}})
-  ELSEIF("${${_list_release}}" STREQUAL "")
-    SET(${_list_release} ${${_list_debug}})
-  ENDIF()
-
 ENDMACRO()
index 80cbd97d478f612d006d51dbc861ec738a21e5cb..29c9be531f88b298b7450509d677377486183767 100644 (file)
@@ -24,6 +24,7 @@
 #   METIS_VERSION
 #   METIS_VERSION_MAJOR
 #   METIS_VERSION_MINOR
+#   METIS_VERSION_SUBMINOR
 #
 
 INCLUDE(FindPackageHandleStandardArgs)
index 173da3893a47c703eb12405735586ce89fa7fa8c..32a6f08497e86f978e5a9093301da39e038d2eed 100644 (file)
@@ -33,23 +33,6 @@ INCLUDE(FindPackageHandleStandardArgs)
 SET_IF_EMPTY(P4EST_DIR "$ENV{P4EST_DIR}")
 SET_IF_EMPTY(SC_DIR "$ENV{SC_DIR}")
 
-#
-# We used to recommend installing p4est with a custom script that
-# compiled p4est twice, once in debug and once in optimized mode.
-# the installation would then have happened into directories
-# $P4EST_DIR/DEBUG and $P4EST_DIR/FAST. If we can find these
-# two directories, then use the FAST directory rather than trying
-# to figure out how we can build deal.II against the two libraries
-# depending on whether we are in debug or optimized mode.
-#
-IF(P4EST_DIR
-   AND EXISTS ${P4EST_DIR}/DEBUG
-   AND EXISTS ${P4EST_DIR}/FAST)
-  MESSAGE(STATUS "Found old-style p4est directory layout")
-  SET (P4EST_DIR ${P4EST_DIR}/FAST)
-ENDIF()
-
-
 #
 # Search for the sc library, usually bundled with p4est. If no SC_DIR was
 # given, take what we chose for p4est.
@@ -57,6 +40,8 @@ ENDIF()
 
 FIND_PATH(P4EST_INCLUDE_DIR p4est_config.h
   HINTS
+    ${P4EST_DIR}/FAST
+    ${P4EST_DIR}/DEBUG
     ${P4EST_DIR}
   PATH_SUFFIXES
     p4est include/p4est include src
@@ -64,49 +49,99 @@ FIND_PATH(P4EST_INCLUDE_DIR p4est_config.h
 
 FIND_PATH(SC_INCLUDE_DIR sc.h
   HINTS
+    ${SC_DIR}/FAST
+    ${SC_DIR}/DEBUG
     ${SC_DIR}
+    ${P4EST_DIR}/FAST
+    ${P4EST_DIR}/DEBUG
     ${P4EST_DIR}
   PATH_SUFFIXES
     sc include/p4est include src sc/src
   )
 
-FIND_LIBRARY(P4EST_LIBRARY
+FIND_LIBRARY(P4EST_LIBRARY_OPTIMIZED
   NAMES p4est
   HINTS
+    ${P4EST_DIR}/FAST
+    ${P4EST_DIR}/DEBUG
     ${P4EST_DIR}
   PATH_SUFFIXES
     lib${LIB_SUFFIX} lib64 lib src
   )
 
-FIND_LIBRARY(SC_LIBRARY
+FIND_LIBRARY(P4EST_LIBRARY_DEBUG
+  NAMES p4est
+  HINTS
+    ${P4EST_DIR}/DEBUG
+  PATH_SUFFIXES
+    lib${LIB_SUFFIX} lib64 lib src
+  )
+
+FIND_LIBRARY(SC_LIBRARY_OPTIMIZED
   NAMES sc
   HINTS
+    ${SC_DIR}/FAST
+    ${SC_DIR}/DEBUG
     ${SC_DIR}
+    ${P4EST_DIR}/FAST
+    ${P4EST_DIR}/DEBUG
     ${P4EST_DIR}
   PATH_SUFFIXES
     lib${LIB_SUFFIX} lib64 lib src sc/src
   )
 
-SET(_output ${P4EST_LIBRARY} ${SC_LIBRARY})
+FIND_LIBRARY(SC_LIBRARY_DEBUG
+  NAMES sc
+  HINTS
+    ${SC_DIR}/DEBUG
+    ${P4EST_DIR}/DEBUG
+  PATH_SUFFIXES
+    lib${LIB_SUFFIX} lib64 lib src sc/src
+  )
+
+SET(_output ${P4EST_LIBRARY_OPTMIZED} ${SC_LIBRARY_OPTIMIZED})
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(P4EST DEFAULT_MSG
   _output # Cosmetic: Gives nice output
-  P4EST_LIBRARY
-  SC_LIBRARY
+  P4EST_LIBRARY_OPTIMIZED
+  SC_LIBRARY_OPTIMIZED
   P4EST_INCLUDE_DIR
   SC_INCLUDE_DIR
   )
 
 MARK_AS_ADVANCED(
-  P4EST_LIBRARY
+  P4EST_LIBRARY_OPTIMIZED
+  P4EST_LIBRARY_DEBUG
   P4EST_INCLUDE_DIR
-  SC_LIBRARY
+  SC_LIBRARY_OPTIMIZED
+  SC_LIBRARY_DEBUG
   SC_INCLUDE_DIR
   )
 
+
 IF(P4EST_FOUND)
-  SET(P4EST_LIBRARIES
-    ${P4EST_LIBRARY}
-    ${SC_LIBRARY}
+
+  IF( ( "${P4EST_LIBRARY_OPTIMIZED}" STREQUAL "${P4EST_LIBRARY_DEBUG}"
+        AND
+        "${SC_LIBRARY_OPTIMIZED}" STREQUAL "${SC_LIBRARY_DEBUG}" )
+      OR P4EST_LIBRARY_DEBUG MATCHES "-NOTFOUND"
+      OR SC_LIBRARY_DEBUG MATCHES "-NOTFOUND" )
+    SET(P4EST_LIBRARIES
+      ${P4EST_LIBRARY_OPTIMIZED}
+      ${SC_LIBRARY_OPTIMIZED}
+      )
+  ELSE()
+    SET(P4EST_LIBRARIES
+      optimized
+      ${P4EST_LIBRARY_OPTIMIZED}
+      ${SC_LIBRARY_OPTIMIZED}
+      debug
+      ${P4EST_LIBRARY_DEBUG}
+      ${SC_LIBRARY_DEBUG}
+      general
+      )
+  ENDIF()
+
+  LIST(APPEND P4EST_LIBRARIES
     ${LAPACK_LIBRARIES} # for good measure
     ${MPI_C_LIBRARIES} # for good measure
     )
@@ -123,6 +158,7 @@ IF(P4EST_FOUND)
   IF("${P4EST_MPI_STRING}" STREQUAL "")
     SET(P4EST_WITH_MPI FALSE)
   ELSE()
+
     SET(P4EST_WITH_MPI TRUE)
   ENDIF()
 
index b347b32ccf7cb9304d2b366a52ede902ffa69f0d..2ff349ebac8b26073404ff122a6a2760e58e8c10 100644 (file)
@@ -141,6 +141,8 @@ FOREACH(_library ${Trilinos_LIBRARIES})
     NO_CMAKE_FIND_ROOT_PATH
     )
 
+  MARK_AS_ADVANCED(TRILINOS_LIBRARY_${_library})
+
   IF(TRILINOS_LIBRARY_${_library} MATCHES "-NOTFOUND")
     SET(TRILINOS_CONFIG_FOUND FALSE)
   ELSE()
index aeb340ced39091b0807b00c8cd5709cdedbe2592..df14dc07d3bc0d9deb6d4a67d72906babe08d56d 100644 (file)
 # SET(METIS_FOUND TRUE CACHE BOOL "")
 # SET(METIS_LIBRARIES "library;and;semicolon;separated;list;of;link;interface" CACHE STRING "")
 # SET(METIS_INCLUDE_DIRS "semicolon;separated;list;of;include;dirs" CACHE STRING "")
+# SET(METIS_VERSION "x.y.z" CACHE STRING "")
+# SET(METIS_VERSION_MAJOR "x" CACHE STRING "")
+# SET(METIS_VERSION_MINOR "y" CACHE STRING "")
+# SET(METIS_VERSION_SUBMINOR "z" CACHE STRING "")
 #
 
 
 # SET(P4EST_LIBRARIES "library;and;semicolon;separated;list;of;link;interface" CACHE STRING "")
 # SET(P4EST_INCLUDE_DIRS "semicolon;separated;list;of;include;dirs" CACHE STRING "")
 # SET(P4EST_WITH_MPI TRUE CACHE BOOL "")
+# SET(P4EST_VERSION "x.y.z.p" CACHE STRING "")
+# SET(P4EST_VERSION_MAJOR "x" CACHE STRING "")
+# SET(P4EST_VERSION_MINOR "y" CACHE STRING "")
+# SET(P4EST_VERSION_SUBMINOR "z" CACHE STRING "")
+# SET(P4EST_VERSION_PATCH "p" CACHE STRING "")
 #
 
 
 # SET(PETSC_VERSION_MAJOR "x" CACHE STRING "")
 # SET(PETSC_VERSION_MINOR "y" CACHE STRING "")
 # SET(PETSC_VERSION_SUBMINOR "z" CACHE STRING "")
+# SET(PETSC_VERSION_PATCH "" CACHE STRING "")
 # SET(PETSC_WITH_MPI_UNI FALSE CACHE BOOL "")
 #
 
 # SET(SLEPC_VERSION_MAJOR "x" CACHE STRING "")
 # SET(SLEPC_VERSION_MINOR "y" CACHE STRING "")
 # SET(SLEPC_VERSION_SUBMINOR "z" CACHE STRING "")
+# SET(SLEPC_VERSION_PATCH "" CACHE STRING "")
 # SET(SLEPC_WITH_MPI_UNI FALSE CACHE BOOL "")
 #
 
index cc3d35bffbfb083ed0b66510c1a831775da7f846..941beef63ef6dad71bb3b73814d4cb78c8657d5d 100644 (file)
@@ -5,15 +5,35 @@
     <link href="screen.css" rel="StyleSheet" type="text/css">
     <title>The deal.II Online Documentation</title>
     <meta name="author" content="the deal.II authors <authors@dealii.org>">
-    <meta name="copyright" content="Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors">
+    <meta name="copyright" content="Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by the deal.II authors">
     <meta name="date" content="2006/02/07 22:49:01">
     <meta name="keywords" content="deal.II">
     <meta name="svn_id" content="$Id$">
   </head>
   <body>
 
+
+
+
     <h2>Online documentation</h2>
 
+    <table class="tutorial" width="40%">
+      <tr><th colspan="2"><b><small>Table of contents</small></b></th></tr>
+      <tr><td valign="top">
+         <ul>
+           <li> <a href="#readme.html">ReadMe</a></li>
+           <li> <a href="#tutorials">Tutorials</a></li>
+           <li> <a href="#API">Programming interface</a></li>
+           <li> <a href="#dev">Development information</a></li>
+           <li> <a href="#reports">Reports</a></li>
+           <li> <a href="#publications">Publications</a></li>
+           <li> <a href="#license">Copyright and licence</a></li>
+         </ul>
+       </td>
+      </tr>
+    </table>
+
+
     <p>
       <acronym>deal.II</acronym> comes with quite extensive online
       documentation, which falls into several categories. They are
@@ -21,7 +41,7 @@
     </p>
 
 
-    <h3><a href="readme.html">README</a></h3>
+    <h3><a href="readme.html">ReadMe</a></h3>
 
     <p>
       First, there is the <a href="readme.html" target="body">README file</a> of
@@ -29,7 +49,7 @@
       installation, and copyright.
     </p>
 
-    <h3>Tutorials</h3>
+    <h3><a href="tutorials">Tutorials</a></h3>
 
     <p>
       The <a href="doxygen/tutorial/index.html"
@@ -49,7 +69,7 @@
     </p>
 
 
-    <h3>Programming interface</h3>
+    <h3><a href="API">Programming interface</a></h3>
 
     <p>
       The <a href="doxygen/deal.II/index.html" target="_top">programming
     </p>
 
 
-    <h3>Development information</h3>
+    <h3><a name="dev">Development information</a></h3>
 
     <p>
       If you plan to <a href="development/index.html"
     </p>
 
 
-    <h3>Reports</h3>
+    <h3><a name="reports">Reports</a></h3>
 
     <p>
       There are a number of papers that describe the overall design or
       </ul>
 
 
-      <h3>Publications</h3>
+    <h3><a name="publications">Publications</a></h3>
 
     <p>
       A <a href="publications/index.html" target="body">list of
     </p>
 
 
-    <h3>Copyright and License</h3>
+    <h3><a name="license">Copyright and License</a></h3>
 
     <p> <acronym>deal.II</acronym> is copyright of the
       <a href="authors.html" target="body">deal.II authors</a>.
index 93d16b5ed883ce946a1b95168c766419a9a66a09..e4ff71cee2a45c1b37ddc01a890579ea0958ffd3 100644 (file)
@@ -31,6 +31,18 @@ inconvenience this causes.
   <br>
   (Wolfgang Bangerth, 2013/08/09)
   </li>
+
+  <li>
+  Changed: The typedefs DataOut::cell_iterator and
+  DataOut::active_cell_iterator were previously defined as
+  DoFHandler::(active)_cell_iterator, while they are now
+  Triangulation::(active)_cell_iterator. This is necessary to support DataOut
+  on multiple DoFHandler objects. This affects possible overloading of
+  DataOut::next_cell(cell_iterator). Use the typedef
+  DataOut::(active)_cell_iterator as argument type instead.
+  <br>
+  (Martin Kronbichler, 2013/07/24)
+  </li>
 </ol>
 
 
@@ -56,6 +68,77 @@ inconvenience this causes.
 <h3>Specific improvements</h3>
 
 <ol>
+  <li>
+  Fixed: The ParameterHandler class can now deal with including one parameter
+  file from another.
+  <br>
+  (Wolfgang Bangerth, 2013/08/25)
+  </li>
+
+  <li>
+  New: The method VectorTools::compute_normal_flux_constraints can be used to
+  force a vector finite element function to be normal to the boundary.
+  <br>
+  (Martin Kronbichler, 2013/08/23)
+  </li>
+
+  <li>
+  Improved: MappingQ now uses the points of the Gauss-Lobatto quadrature
+  formula as support points instead of equispaced ones. This allows its use
+  for high polynomial orders and also gives better interpolation of circular
+  boundaries. Beware that mappings of order three and higher will behave
+  slightly differently now (usually better).
+  <br>
+  (Martin Kronbichler, 2013/08/23)
+  </li>
+
+  <li>
+  Improved: Several .cc files in the deal.II directory have been split in
+  order to better utilize multiple processors when compiling in parallel and
+  reduce memory requirements of the compilation stage.
+  <br>
+  (Martin Kronbichler, 2013/08/22)
+  </li>
+
+  <li>
+  Fixed: The ParameterHandler::declare_entry() did not check that the
+  default value of a parameter indeed satisfies the pattern given for this
+  parameter (despite a statement in the documentation that this checking
+  would happen). This is now fixed.
+  <br>
+  (Wolfgang Bangerth, 2013/08/21)
+  </li>
+
+  <li>
+  New: Patterns::List and Patterns::Map now accept a string
+  different than the default comma that denotes the separator
+  between entries of the list or map.
+  <br>
+  (Wolfgang Bangerth, 2013/08/21)
+  </li>
+
+  <li>
+  Fixed: Some operations in the MappingQ class are now done in higher
+  precision arithmetic to mitigate the ill-conditioning that appears
+  when using mappings of high order (say, order 6 or 8 or 10).
+  <br>
+  (Juan Carlos Araujo Cabarcas, 2013/08/20)
+  </li>
+
+  <li>
+  Fixed: The SLEPcWrappers classes could not be compiled for 64-bit
+  indices. This is now fixed.
+  <br>
+  (Denis Davydov, Wolfgang Bangerth, 2013/08/20)
+  </li>
+
+  <li>
+  Fixed: SolutionTransfer used to crash whenever one transfered in the hp
+  context between cells that use FE_Nothing and FE_Q. This is now fixed.
+  <br>
+  (Krzyszof Bzowski, Wolfgang Bangerth, 2013/08/18)
+  </li>
+
   <li>
   Fixed: Under some circumstances (see http://code.google.com/p/dealii/issues/detail?id=82)
   the DoFTools::make_periodicity_constraints() function could create cycles in
index 2e25ba40fad1ccede1cb838ace3de3dc58a9c29e..dcc5dac01145ceb900348585861700a1f5b74ae8 100644 (file)
@@ -9,7 +9,7 @@ the commands
 @code
 set style data lines
 set size 0.721, 1
-set nokey
+unset key
 plot [-1:1][-1:1] "ball0_mapping_q1.dat"
 @endcode
 or using one of the other filenames. The second line makes sure that
@@ -90,104 +90,101 @@ good accuracy. This is the output of this part of the program:
 Computation of Pi by the area:
 ==============================
 Degree = 1
-cells         eval.pi         error                           
-5       1.9999999999999998      1.1416e+00      -
-20      2.8284271247461898      3.1317e-01      1.87
-80      3.0614674589207178      8.0125e-02      1.97
-320     3.1214451522580520      2.0148e-02      1.99
-1280    3.1365484905459389      5.0442e-03      2.00
-5120    3.1403311569547521      1.2615e-03      2.00
+cells      eval.pi            error      
+    5 1.9999999999999993 1.1416e+00    - 
+   20 2.8284271247461894 3.1317e-01 1.87 
+   80 3.0614674589207178 8.0125e-02 1.97 
+  320 3.1214451522580520 2.0148e-02 1.99 
+ 1280 3.1365484905459393 5.0442e-03 2.00 
+ 5120 3.1403311569547534 1.2615e-03 2.00 
 
 Degree = 2
-cells         eval.pi         error                           
-5       3.1045694996615869      3.7023e-02      -
-20      3.1391475703122276      2.4451e-03      3.92
-80      3.1414377167038303      1.5494e-04      3.98
-320     3.1415829366419019      9.7169e-06      4.00
-1280    3.1415920457576907      6.0783e-07      4.00
-5120    3.1415926155921126      3.7998e-08      4.00
+cells      eval.pi            error      
+    5 3.1045694996615865 3.7023e-02    - 
+   20 3.1391475703122271 2.4451e-03 3.92 
+   80 3.1414377167038303 1.5494e-04 3.98 
+  320 3.1415829366419015 9.7169e-06 4.00 
+ 1280 3.1415920457576911 6.0783e-07 4.00 
+ 5120 3.1415926155921139 3.7998e-08 4.00 
 
 Degree = 3
-cells         eval.pi         error                           
-5       3.1465390309173475      4.9464e-03      -
-20      3.1419461263297386      3.5347e-04      3.81
-80      3.1416154689089382      2.2815e-05      3.95
-320     3.1415940909713274      1.4374e-06      3.99
-1280    3.1415927436051230      9.0015e-08      4.00
-5120    3.1415926592185492      5.6288e-09      4.00
+cells      eval.pi            error      
+    5 3.1410033851499310 5.8927e-04    - 
+   20 3.1415830393583861 9.6142e-06 5.94 
+   80 3.1415925017363837 1.5185e-07 5.98 
+  320 3.1415926512106722 2.3791e-09 6.00 
+ 1280 3.1415926535525962 3.7197e-11 6.00 
+ 5120 3.1415926535892140 5.7923e-13 6.00 
 
 Degree = 4
-cells         eval.pi         error                           
-5       3.1418185737113964      2.2592e-04      -
-20      3.1415963919525050      3.7384e-06      5.92
-80      3.1415927128397780      5.9250e-08      5.98
-320     3.1415926545188264      9.2903e-10      5.99
-1280    3.1415926536042722      1.4479e-11      6.00
-5120    3.1415926535899668      1.7343e-13      6.38
-
+cells      eval.pi            error       
+    5 3.1415871927401127 5.4608e-06     - 
+   20 3.1415926314742437 2.2116e-08  7.95 
+   80 3.1415926535026228 8.7170e-11  7.99 
+  320 3.1415926535894529 3.4036e-13  8.00 
+ 1280 3.1415926535897927 2.9187e-16 10.19 
+ 5120 3.1415926535897944 1.3509e-15 -2.21 
 
 Computation of Pi by the perimeter:
 ===================================
 Degree = 1
-cells         eval.pi         error                           
-5       2.8284271247461903      3.1317e-01      -
-20      3.0614674589207183      8.0125e-02      1.97
-80      3.1214451522580524      2.0148e-02      1.99
-320     3.1365484905459393      5.0442e-03      2.00
-1280    3.1403311569547525      1.2615e-03      2.00
-5120    3.1412772509327729      3.1540e-04      2.00
+cells      eval.pi            error      
+    5 2.8284271247461898 3.1317e-01    - 
+   20 3.0614674589207178 8.0125e-02 1.97 
+   80 3.1214451522580520 2.0148e-02 1.99 
+  320 3.1365484905459393 5.0442e-03 2.00 
+ 1280 3.1403311569547525 1.2615e-03 2.00 
+ 5120 3.1412772509327729 3.1540e-04 2.00 
 
 Degree = 2
-cells         eval.pi         error                           
-5       3.1248930668550599      1.6700e-02      -
-20      3.1404050605605454      1.1876e-03      3.81
-80      3.1415157631807014      7.6890e-05      3.95
-320     3.1415878042798613      4.8493e-06      3.99
-1280    3.1415923498174538      3.0377e-07      4.00
-5120    3.1415926345932004      1.8997e-08      4.00
+cells      eval.pi            error      
+    5 3.1248930668550594 1.6700e-02    - 
+   20 3.1404050605605449 1.1876e-03 3.81 
+   80 3.1415157631807014 7.6890e-05 3.95 
+  320 3.1415878042798617 4.8493e-06 3.99 
+ 1280 3.1415923498174534 3.0377e-07 4.00 
+ 5120 3.1415926345932004 1.8997e-08 4.00 
 
 Degree = 3
-cells         eval.pi         error                           
-5       3.1442603311164286      2.6677e-03      -
-20      3.1417729561193588      1.8030e-04      3.89
-80      3.1416041192612365      1.1466e-05      3.98
-320     3.1415933731961760      7.1961e-07      3.99
-1280    3.1415926986118001      4.5022e-08      4.00
-5120    3.1415926564043946      2.8146e-09      4.00
+cells      eval.pi            error      
+    5 3.1414940401456057 9.8613e-05    - 
+   20 3.1415913432549156 1.3103e-06 6.23 
+   80 3.1415926341726914 1.9417e-08 6.08 
+  320 3.1415926532906893 2.9910e-10 6.02 
+ 1280 3.1415926535851360 4.6571e-12 6.01 
+ 5120 3.1415926535897203 7.2845e-14 6.00 
 
 Degree = 4
-cells         eval.pi         error                           
-5       3.1417078926581086      1.1524e-04      -
-20      3.1415945317216001      1.8781e-06      5.94
-80      3.1415926832497720      2.9660e-08      5.98
-320     3.1415926540544636      4.6467e-10      6.00
-1280    3.1415926535970535      7.2602e-12      6.00
-5120    3.1415926535899010      1.0805e-13      6.07
+cells      eval.pi            error      
+    5 3.1415921029432576 5.5065e-07    - 
+   20 3.1415926513737600 2.2160e-09 7.96 
+   80 3.1415926535810712 8.7218e-12 7.99 
+  320 3.1415926535897594 3.3668e-14 8.02 
+ 1280 3.1415926535897922 1.0617e-15 4.99 
+ 5120 3.1415926535897931 1.0061e-16 3.40 
 @endcode
 
 
 
-One of the immediate observations from the output is that in all cases
-the values converge quickly to the true value of
-$\pi=3.141592653589793238462643$. Note that for the $Q_4$ mapping, the last
-number is correct to 13 digits in both computations, which is already
-quite a lot. However, also note that for the $Q_1$ mapping, even on the
-finest grid the accuracy is significantly worse than on the coarse
-grid for a $Q_4$ mapping!
+One of the immediate observations from the output is that in all cases the
+values converge quickly to the true value of
+$\pi=3.141592653589793238462643$. Note that for the $Q_4$ mapping, we are
+already in the regime of roundoff errors and the convergence rate levels off,
+which is already quite a lot. However, also note that for the $Q_1$ mapping,
+even on the finest grid the accuracy is significantly worse than on the coarse
+grid for a $Q_3$ mapping!
 
 
 
-The last column of the output shows the convergence order, in powers
-of the mesh width $h$. In the introduction, we had stated that
-the convergence order for a $Q_p$ mapping should be
-$h^{p+1}$. However, in the example shown, the $Q_2$ and $Q_4$
-mappings show a convergence order of $h^{p+2}$! This at
-first surprising fact is readily explained by the particular boundary
-we have chosen in this example. In fact, the circle is described by the function
-$\sqrt{1-x^2}$, which has the series expansion 
-$1-x^2/2-x^4/8-x^6/16+\ldots$
-around $x=0$. Thus, for the quadratic mapping where the
-truncation error of the quadratic approximation should be cubic, there
-is no such term but only a quartic one, which raises the convergence
-order to 4, instead of 3. The same happens for the $Q_4$ mapping.
+The last column of the output shows the convergence order, in powers of the
+mesh width $h$. In the introduction, we had stated that the convergence order
+for a $Q_p$ mapping should be $h^{p+1}$. However, in the example shown, the
+order is rather $h^{2p}$! This at first surprising fact is explained by the
+properties of the $Q_p$ mapping. At order <i>p</i>, it uses support points
+that are based on the <i>p</i>+1 point Gauss-Lobatto quadrature rule that
+selects the support points in such a way that the quadrature rule converges at
+order 2<i>p</i>. Even though these points are here only used for interpolation
+of a <i>p</i>th order polynomial, we get a superconvergence effect when
+numerically evaluating the integral that actually gives this high order of
+convergence.
 
index f91bbfc666f86db6d09e5f3d417964a2b0ec5f27..d2d982b129614ab8296410b07aaacda8b7953ad0 100644 (file)
@@ -1692,7 +1692,7 @@ namespace Step14
       // Finally, we have by now only integrated the gradients of the shape
       // functions, not taking their mean value. We fix this by dividing by
       // the measure of the volume over which we have integrated:
-      rhs.scale (1./total_volume);
+      rhs /= total_volume;
     }
 
 
index 81a5202a62a33e6e815857cd44806fb8522fcbd0..37c7826788d35e8f3928c01451c57b5fc23f4888 100644 (file)
@@ -217,7 +217,7 @@ double Input<dim>::obstacle_function(double x, double y) {
 }
 
 // As mentioned above this function reads in the
-// obstacle datas and stores them in the std::vector
+// obstacle data and stores them in the std::vector
 // obstacle_data. It will be used only in run ().
 template<int dim>
 void Input<dim>::read_obstacle(const char* name) {
@@ -244,11 +244,11 @@ void Input<dim>::read_obstacle(const char* name) {
 
 // This class provides an interface
 // for a constitutive law. In this
-// example we are using an elasto
-// plastic material behavior with linear,
+// example we are using an elastoplastic
+// material behavior with linear,
 // isotropic hardening.
-// For gamma = 0 we obtain perfect elasto
-// plasticity behavior.
+// For gamma = 0 we obtain perfect elastoplastic
+// behavior.
 template<int dim>
 class ConstitutiveLaw {
 public:
@@ -312,7 +312,8 @@ ConstitutiveLaw<dim>::ConstitutiveLaw(double _E, double _nu, double _sigma_0,
 
 // @sect3{ConstitutiveLaw::ConstitutiveLaw}
 
-// Calculates the strain for the shape functions.
+// Calculates the strain $\varepsilon(\varphi)=\dfrac{1}{2}\left(\nabla\varphi + \nabla\varphi^T$
+// for the shape functions $\varphi$.
 template<int dim>
 inline SymmetricTensor<2, dim> ConstitutiveLaw<dim>::get_strain(
                const FEValues<dim> &fe_values, const unsigned int shape_func,
@@ -331,7 +332,9 @@ inline SymmetricTensor<2, dim> ConstitutiveLaw<dim>::get_strain(
 // deviator part of the stresses in a quadrature point back to
 // the yield stress plus the linear isotropic hardening.
 // Also we sum up the elastic and the plastic quadrature
-// points.
+// points. We need this function to calculate the nonlinear
+// residual in
+// PlasticityContactProblem::residual_nl_system(TrilinosWrappers::MPI::Vector &u).
 template<int dim>
 void ConstitutiveLaw<dim>::plast_linear_hardening(
                SymmetricTensor<4, dim> &stress_strain_tensor,
@@ -364,8 +367,16 @@ void ConstitutiveLaw<dim>::plast_linear_hardening(
 
 // @sect3{ConstitutiveLaw::linearized_plast_linear_hardening}
 
-// This function returns the linearized stress strain tensor.
-// It contains the derivative of the nonlinear constitutive law.
+// This function returns the linearized stress strain tensor
+// in the solution $u^{i-1}$ of the previous Newton $i-1$ step.
+// The parameter strain_tensor $\varepsilon(u^{i-1})$ is calculated
+// by $u^{i-1}$. It contains the derivative of the nonlinear
+// constitutive law. As the result this function returns
+// the stress_strain_tensor of the nonlinear problem as well as
+// the stress_strain_tensor_linearized of the linearized problem.
+// See
+// PlasticityContactProblem::assemble_nl_system(TrilinosWrappers::MPI::Vector &u)
+// where this function is used.
 template<int dim>
 void ConstitutiveLaw<dim>::linearized_plast_linear_hardening(
                SymmetricTensor<4, dim> &stress_strain_tensor_linearized,
@@ -426,7 +437,7 @@ double RightHandSide<dim>::value(const Point<dim> &p,
        if (component == 1)
                return_value = 0.0;
        if (component == 2)
-         return_value = 0.0;//-26923.07692;
+         return_value = 0.0;
 
        return return_value;
 }
@@ -592,7 +603,7 @@ private:
        void
        output_results(const std::string &title);
        void
-       output_for_benchmark(const unsigned int cycle);
+       output_contact_force(const unsigned int cycle);
 
        double to_refine_factor;
        double to_coarsen_factor;
@@ -606,6 +617,9 @@ private:
        FESystem<dim> fe;
        DoFHandler<dim> dof_handler;
 
+       // We are using the SolutionTransfer class to interpolate the
+       // solution on the new refined mesh. It appears in th refine_grid()
+       // and the run() function.
        std_cxx1x::shared_ptr<
                        parallel::distributed::SolutionTransfer<dim,
                                        TrilinosWrappers::MPI::Vector> > soltrans;
@@ -1755,10 +1769,24 @@ void PlasticityContactProblem<dim>::output_results(
        move_mesh(tmp);
 }
 
-// @sect4{PlasticityContactProblem::output_for_benchmark}
-
+// @sect4{PlasticityContactProblem::output_contact_force}
+
+// This function provides the contact force by calculating
+// an integral over the contact pressure in z-directions
+// over the contact area. For this purpose we set the contact
+// pressure lambda to 0 for all inactive dofs. For all
+// active dofs we lambda contains the quotient of the nonlinear
+// residual (resid_vector) and corresponding diagonal entry
+// of the mass matrix (diag_mass_matrix_vector). Because it is
+// not unlikely that hanging nodes shows up in the contact area
+// it is important to apply contraints_hanging_nodes.distribute
+// to the distributed_lambda vector.
+// To calculate the contact pressure in a certain point in the
+// contact area, we have make use of the Functions::FEFieldFunction
+// In parallel this is little tricky because we have to find the
+// process with the right cell which contains this point.
 template<int dim>
-void PlasticityContactProblem<dim>::output_for_benchmark(
+void PlasticityContactProblem<dim>::output_contact_force(
                const unsigned int cycle) {
        Functions::FEFieldFunction<dim, DoFHandler<dim>,
                        TrilinosWrappers::MPI::Vector> solution_function(dof_handler,
@@ -1819,7 +1847,7 @@ void PlasticityContactProblem<dim>::output_for_benchmark(
                typename DoFHandler<dim>::active_cell_iterator cell =
                                dof_handler.begin_active(), endc = dof_handler.end();
                for (; cell != endc; ++cell)
-                       if (cell->is_locally_owned())
+                 if (cell->is_locally_owned())
                                for (unsigned int face = 0;
                                                face < GeometryInfo < dim > ::faces_per_cell; ++face)
                                        if (cell->face(face)->at_boundary()
index d5ecfd4b7008e252facf3bcecebc0bdde3044b07..22dc984e0827457d4f9ee3dbc75983941d4a5445 100644 (file)
@@ -16,6 +16,7 @@ to all of the degrees of freedom in the adjacent elements.  The resulting
 discrete equations yield very large linear systems very quickly, especially
 for systems of equations in dim=2 or dim=3.  
 
+<h4> Reducing the size of the linear system </h4>
 To alleviate the computational cost of solving such large linear systems, 
 the hybridizable discontinuous Galerkin (HDG) methodology has recently been 
 developed by Cockburn and co-workers 
@@ -40,12 +41,45 @@ element solutions no longer couple to neighboring elements.  This is known as th
 solution process.
   <li>  Use the local element solutions to construct the global problem for the 
 trace values.  These are the only globally coupled unknowns.
-  <li>  Modify the local solutions from the computed trace values.
+  <li>  Reconstruct the local solutions from the computed trace values.
 </ol>
 
+The above procedure also has a linear algebra interpretation and referred to
+as static condensation. Let us write the complete linear system associated to
+the HDG problem as a block system with the discrete DG variables <i>U</i> as
+first block and the skeleton variables $\Lambda$ as the second block:
+@f{eqnarray*}
+\begin{pmatrix} A & B \\ C & D \end{pmatrix}
+\begin{pmatrix} U \\ \Lambda \end{pmatrix}
+=
+\begin{pmatrix} F \\ G \end{pmatrix}
+@f}
+Our aim is now to eliminate the <i>U</i> block with a Schur complement
+approach similar to step-20, which results in the following two steps:
+@f{eqnarray*}
+(D - C A^{-1} B) \Lambda &=& G - C A^{-1} F \\
+A U &=& F - B \Lambda
+@f}
+The steps in the Dirichlet-to-Neumann map concept hence correspond to
+<ol>
+  <li> constructing the Schur complement matrix $D-C A^{-1} B$ and right hand side $G - C A^{-1} F$,
+  <li> solving the Schur complement system for $\Lambda$, and
+  <li> solving the equation for <i>U</i> using the second equation which uses $\Lambda$.
+</ol>
+
+The important ingredient from the linear algebra point of view is that the
+matrix <i>A</i> is block-diagonal with block size equal to the number of
+degrees of freedom of the interior DG variables which are always only related
+to a single cell. The coupling to other cells is introduced by the matrices
+<i>B</i> and <i>C</i> over the skeleton variable. The block-diagonality of
+<i>A</i> and the structure in <i>B</i> and <i>C</i> allow us to invert the
+matrix <i>A</i> element by element (the local solution of the Dirichelt
+problem) and subtract $CA^{-1}B$ from $D$.
+
+<h4> Solution quality and rates of convergence</h4>
 Another criticism of traditional DG methods is that the approximate fluxes
-converge suboptimally.   The local HDG solutions can be shown to converge
-as $\mathcal{O}(h^{p+1})$.  Additionally, a super-convergence property can 
+converge suboptimally.  The local HDG solutions can be shown to converge
+as $\mathcal{O}(h^{p+1})$, i.e., at optimal order.  Additionally, a super-convergence property can 
 be used to post-process a new approximate solution that converges at the 
 rate $\mathcal{O}(h^{p+2})$.
 
index ae6e002753f9f0753a3165d1e54a17462d68715d..96eabb17247699eb6f9d9dfb7473848f8eb80131 100644 (file)
@@ -7,43 +7,43 @@ the convergence tables look the following:
 
 @code
 Q1 elements, adaptive refinement:
-cells dofs   val L2    grad L2  val L2-post 
-    4    24 6.101e+00 1.065e+01   5.098e+00 
-   10    58 3.168e+00 9.223e+00   2.431e+00 
-   28   148 2.888e+00 9.368e+00   2.644e+00 
-   55   272 6.756e-01 4.088e+00   2.400e-01 
-  109   578 2.175e-01 1.529e+00   7.350e-02 
-  214  1072 9.783e-02 9.006e-01   2.219e-02 
-  409  2056 4.812e-02 5.193e-01   1.081e-02 
-  811  3880 2.714e-02 2.971e-01   4.669e-03 
- 1555  7204 1.365e-02 1.789e-01   2.627e-03 
- 2956 13198 7.919e-03 1.009e-01   1.006e-03 
+cells dofs   val L2    grad L2  val L2-post
+   16    80 1.804e+01 2.207e+01   1.798e+01
+   31   170 9.874e+00 1.322e+01   9.798e+00
+   61   314 7.452e-01 3.793e+00   4.891e-01
+  121   634 3.240e-01 1.511e+00   2.616e-01
+  238  1198 8.585e-02 8.212e-01   1.808e-02
+  454  2290 4.802e-02 5.178e-01   2.195e-02
+  898  4378 2.561e-02 2.947e-01   4.318e-03
+ 1720  7864 1.306e-02 1.664e-01   2.978e-03
+ 3271 14638 7.025e-03 9.815e-02   1.075e-03
+ 6217 27214 4.119e-03 6.407e-02   9.975e-04
 
 Q1 elements, global refinement:
-cells dofs      val L2        grad L2      val L2-post   
-   16    80 4.570e+00    - 1.221e+01    - 4.333e+00    -
-   36   168 1.869e+00 2.20 7.299e+00 1.27 1.734e+00 2.26
-   64   288 7.177e-01 3.33 4.218e+00 1.91 2.538e-01 6.68
-  144   624 2.729e-01 2.38 1.867e+00 2.01 6.110e-02 3.51
-  256  1088 1.493e-01 2.10 1.046e+00 2.01 2.878e-02 2.62
-  576  2400 6.964e-02 1.88 4.847e-01 1.90 9.202e-03 2.81
- 1024  4224 4.018e-02 1.91 2.785e-01 1.93 4.027e-03 2.87
+cells dofs      val L2        grad L2      val L2-post
+   16    80 1.804e+01    - 2.207e+01    - 1.798e+01    -
+   36   168 6.125e+00 2.66 9.472e+00 2.09 6.084e+00 2.67
+   64   288 9.785e-01 6.38 4.260e+00 2.78 7.102e-01 7.47
+  144   624 2.730e-01 3.15 1.866e+00 2.04 6.115e-02 6.05
+  256  1088 1.493e-01 2.10 1.046e+00 2.01 2.880e-02 2.62
+  576  2400 6.965e-02 1.88 4.846e-01 1.90 9.204e-03 2.81
+ 1024  4224 4.018e-02 1.91 2.784e-01 1.93 4.027e-03 2.87
  2304  9408 1.831e-02 1.94 1.264e-01 1.95 1.236e-03 2.91
  4096 16640 1.043e-02 1.96 7.185e-02 1.96 5.306e-04 2.94
- 9216 37248 4.690e-03 1.97 3.228e-02 1.97 1.600e-04 2.96
+ 9216 37248 4.690e-03 1.97 3.228e-02 1.97 1.599e-04 2.96
 
 Q3 elements, global refinement:
-cells dofs      val L2        grad L2      val L2-post   
-   16   160 2.398e-01    - 1.873e+00    - 1.354e-01    -
-   36   336 5.843e-02 3.48 5.075e-01 3.22 1.882e-02 4.87
-   64   576 3.466e-02 1.82 2.534e-01 2.41 4.326e-03 5.11
-  144  1248 8.297e-03 3.53 5.925e-02 3.58 6.330e-04 4.74
-  256  2176 2.254e-03 4.53 1.636e-02 4.47 1.403e-04 5.24
-  576  4800 4.558e-04 3.94 3.278e-03 3.96 1.844e-05 5.01
- 1024  8448 1.471e-04 3.93 1.052e-03 3.95 4.378e-06 5.00
- 2304 18816 2.956e-05 3.96 2.104e-04 3.97 5.751e-07 5.01
- 4096 33280 9.428e-06 3.97 6.697e-05 3.98 1.362e-07 5.01
- 9216 74496 1.876e-06 3.98 1.330e-05 3.99 1.817e-08 4.97
+cells dofs      val L2        grad L2      val L2-post
+   16   160 3.613e-01    - 1.891e+00    - 3.020e-01    - 
+   36   336 6.411e-02 4.26 5.081e-01 3.24 3.238e-02 5.51 
+   64   576 3.480e-02 2.12 2.533e-01 2.42 5.277e-03 6.31 
+  144  1248 8.297e-03 3.54 5.924e-02 3.58 6.330e-04 5.23 
+  256  2176 2.254e-03 4.53 1.636e-02 4.47 1.403e-04 5.24 
+  576  4800 4.558e-04 3.94 3.277e-03 3.96 1.844e-05 5.01 
+ 1024  8448 1.471e-04 3.93 1.052e-03 3.95 4.378e-06 5.00 
+ 2304 18816 2.956e-05 3.96 2.104e-04 3.97 5.750e-07 5.01 
+ 4096 33280 9.428e-06 3.97 6.697e-05 3.98 1.362e-07 5.01 
+ 9216 74496 1.876e-06 3.98 1.330e-05 3.99 1.788e-08 5.01 
 @endcode
 
 
@@ -58,43 +58,43 @@ postprocessed scalar variable at fifth order.
 The same convergence rates are observed in 3d.
 @code
 Q1 elements, adaptive refinement:
-cells   dofs    val L2    grad L2  val L2-post 
-     8     144 3.846e+00 1.519e+01   2.388e+00 
-    29     500 2.800e+00 9.885e+00   1.185e+00 
-   113    1792 1.772e+00 9.911e+00   1.423e+00 
-   379    5736 6.057e-01 5.011e+00   2.180e-01 
-  1317   19412 1.542e-01 1.465e+00   4.176e-02 
-  4579   64768 5.059e-02 5.615e-01   9.563e-03 
- 14596  199552 2.128e-02 3.124e-01   4.599e-03 
- 46180  611380 1.032e-02 1.623e-01   1.643e-03 
-144859 1864212 4.996e-03 8.376e-02   6.898e-04 
-451053 5684324 2.516e-03 4.559e-02   2.832e-04 
+cells   dofs    val L2    grad L2  val L2-post
+     8     144 7.122e+00 1.941e+01   6.102e+00 
+    29     500 3.309e+00 1.023e+01   2.145e+00 
+   113    1792 2.204e+00 1.023e+01   1.912e+00 
+   379    5732 6.085e-01 5.008e+00   2.233e-01 
+  1317   19412 1.543e-01 1.464e+00   4.196e-02 
+  4579   64768 5.058e-02 5.611e-01   9.521e-03 
+ 14596  199552 2.129e-02 3.122e-01   4.569e-03 
+ 46180  611400 1.033e-02 1.622e-01   1.684e-03 
+144859 1864212 5.007e-03 8.371e-02   7.364e-04 
+451060 5684508 2.518e-03 4.562e-02   3.070e-04 
 
 Q1 elements, global refinement:
-cells   dofs       val L2          grad L2       val L2-post   
-     8     144 3.846e+00     - 1.519e+01     - 2.388e+00     - 
-    27     432 4.677e+00 -0.48 2.158e+01 -0.87 3.441e+00 -0.90 
-    64     960 2.366e+00  2.37 1.228e+01  1.96 1.831e+00  2.19 
-   216    3024 1.225e+00  1.62 8.396e+00  0.94 1.017e+00  1.4
-   512    6912 6.870e-01  2.01 5.314e+00  1.59 2.421e-01  4.99 
-  1728   22464 2.912e-01  2.12 2.494e+00  1.87 8.593e-02  2.56 
-  4096   52224 1.683e-01  1.91 1.455e+00  1.87 4.056e-02  2.61 
- 13824  172800 7.970e-02  1.84 6.866e-01  1.85 1.335e-02  2.74 
- 32768  405504 4.637e-02  1.88 3.986e-01  1.89 5.932e-03  2.82 
-110592 1354752 2.133e-02  1.92 1.831e-01  1.92 1.851e-03  2.87 
+cells   dofs       val L2          grad L2       val L2-post
+     8     144 7.122e+00    - 1.941e+01     - 6.102e+00    - 
+    27     432 5.491e+00 0.64 2.184e+01 -0.29 4.448e+00 0.78 
+    64     960 3.646e+00 1.42 1.299e+01  1.81 3.306e+00 1.03 
+   216    3024 1.595e+00 2.04 8.550e+00  1.03 1.441e+00 2.0
+   512    6912 6.922e-01 2.90 5.306e+00  1.66 2.511e-01 6.07 
+  1728   22464 2.915e-01 2.13 2.490e+00  1.87 8.588e-02 2.65 
+  4096   52224 1.684e-01 1.91 1.453e+00  1.87 4.055e-02 2.61 
+ 13824  172800 7.972e-02 1.84 6.861e-01  1.85 1.335e-02 2.74 
+ 32768  405504 4.637e-02 1.88 3.984e-01  1.89 5.932e-03 2.82 
+110592 1354752 2.133e-02 1.92 1.830e-01  1.92 1.851e-03 2.87 
 
 Q3 elements, global refinement:
-cells   dofs       val L2        grad L2      val L2-post   
-     8     576 3.845e+00    - 1.742e+01    - 3.550e+00    - 
-    27    1728 8.915e-01 3.60 6.939e+00 2.27 5.865e-01 4.44 
-    64    3840 2.807e-01 4.02 2.713e+00 3.26 1.326e-01 5.17 
-   216   12096 7.866e-02 3.14 7.727e-01 3.10 2.112e-02 4.53 
-   512   27648 3.640e-02 2.68 3.307e-01 2.95 5.224e-03 4.86 
-  1728   89856 8.545e-03 3.57 7.586e-02 3.63 7.642e-04 4.74 
-  4096  208896 2.598e-03 4.14 2.314e-02 4.13 1.783e-04 5.06 
- 13824  691200 5.314e-04 3.91 4.699e-03 3.93 2.355e-05 4.99 
- 32768 1622016 1.723e-04 3.91 1.518e-03 3.93 5.603e-06 4.99 
-110592 5419008 3.482e-05 3.94 3.057e-04 3.95 7.375e-07 5.00 
+cells   dofs       val L2        grad L2      val L2-post
+     8     576 5.670e+00    - 1.868e+01    - 5.462e+00    - 
+    27    1728 1.048e+00 4.16 6.988e+00 2.42 8.011e-01 4.73 
+    64    3840 2.831e-01 4.55 2.710e+00 3.29 1.363e-01 6.16 
+   216   12096 7.883e-02 3.15 7.721e-01 3.10 2.158e-02 4.55 
+   512   27648 3.642e-02 2.68 3.305e-01 2.95 5.231e-03 4.93 
+  1728   89856 8.546e-03 3.58 7.581e-02 3.63 7.640e-04 4.74 
+  4096  208896 2.598e-03 4.14 2.313e-02 4.13 1.783e-04 5.06 
+ 13824  691200 5.314e-04 3.91 4.697e-03 3.93 2.355e-05 4.99 
+ 32768 1622016 1.723e-04 3.91 1.517e-03 3.93 5.602e-06 4.99 
+110592 5419008 3.482e-05 3.94 3.055e-04 3.95 7.374e-07 5.00
 @endcode
 
 
index ab772a39a11872e17468c8099559bdcf46306def..9049e88e1a0ff0ce5843bc1cc6baa7504fa55bd1 100644 (file)
@@ -33,7 +33,7 @@
 #include <deal.II/lac/vector.h>
 #include <deal.II/lac/full_matrix.h>
 #include <deal.II/lac/compressed_simple_sparsity_pattern.h>
-#include <deal.II/lac/solver_gmres.h>
+#include <deal.II/lac/solver_bicgstab.h>
 #include <deal.II/lac/precondition.h>
 #include <deal.II/grid/tria.h>
 #include <deal.II/grid/tria_accessor.h>
@@ -738,9 +738,11 @@ Step51<dim>::assemble_system_one_cell (const typename DoFHandler<dim>::active_ce
           for (unsigned int q=0; q<n_face_q_points; ++q)
             {
               const double JxW = scratch.fe_face_values.JxW(q);
+              const Point<dim> quadrature_point =
+                scratch.fe_face_values.quadrature_point(q);
               const Point<dim> normal = scratch.fe_face_values.normal_vector(q);
               const Tensor<1,dim> convection
-                = scratch.convection_velocity.value(scratch.fe_face_values.quadrature_point(q));
+                = scratch.convection_velocity.value(quadrature_point);
               const double tau_stab = (tau_stab_diffusion +
                                        std::abs(convection * normal));
 
@@ -792,11 +794,12 @@ Step51<dim>::assemble_system_one_cell (const typename DoFHandler<dim>::active_ce
                       (cell->face(face)->boundary_indicator() == 1))
                     {
                       const double neumann_value =
-                        scratch.exact_solution.value(scratch.fe_face_values.quadrature_point(q));
+                        - scratch.exact_solution.gradient (quadrature_point) * normal
+                        + convection * normal * scratch.exact_solution.value(quadrature_point);
                       for (unsigned int i=0; i<scratch.fe_support_on_face[face].size(); ++i)
                         {
                           const unsigned int ii=scratch.fe_support_on_face[face][i];
-                          task_data.cell_vector(ii) -= scratch.tr_phi[i] * neumann_value * JxW;
+                          task_data.cell_vector(ii) += scratch.tr_phi[i] * neumann_value * JxW;
                         }
                     }
                 }
@@ -815,9 +818,9 @@ Step51<dim>::assemble_system_one_cell (const typename DoFHandler<dim>::active_ce
                   {
                     const unsigned int ii=scratch.fe_local_support_on_face[face][i];
                     scratch.l_rhs(ii) -= (scratch.q_phi[i] * normal
-                                  +
-                                  scratch.u_phi[i] * (convection * normal - tau_stab)
-                                  ) * scratch.trace_values[q] * JxW;
+                                          +
+                                          scratch.u_phi[i] * (convection * normal - tau_stab)
+                                          ) * scratch.trace_values[q] * JxW;
                   }
             }
         }
@@ -843,12 +846,12 @@ template <int dim>
 void Step51<dim>::solve ()
 {
   SolverControl solver_control (system_matrix.m()*10,
-                                1e-10*system_rhs.l2_norm());
-  SolverGMRES<> solver (solver_control, 50);
+                                1e-11*system_rhs.l2_norm());
+  SolverBicgstab<> solver (solver_control, false);
   solver.solve (system_matrix, solution, system_rhs,
                 PreconditionIdentity());
 
-  std::cout << "   Number of GMRES iterations: " << solver_control.last_step()
+  std::cout << "   Number of BiCGStab iterations: " << solver_control.last_step()
             << std::endl;
 
   system_matrix.clear();
@@ -1067,46 +1070,62 @@ void Step51<dim>::refine_grid (const unsigned int cycle)
   if (cycle == 0)
     {
       GridGenerator::subdivided_hyper_cube (triangulation, 2, -1, 1);
+      triangulation.refine_global(3-dim);
     }
   else
     switch (refinement_mode)
       {
       case global_refinement:
         {
-            triangulation.clear();
-            GridGenerator::subdivided_hyper_cube (triangulation, 2+(cycle%2), -1, 1);
-            triangulation.refine_global(3-dim+cycle/2);
+          triangulation.clear();
+          GridGenerator::subdivided_hyper_cube (triangulation, 2+(cycle%2), -1, 1);
+          triangulation.refine_global(3-dim+cycle/2);
           break;
         }
 
       case adaptive_refinement:
-      {
-        Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
+        {
+          Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
 
-        FEValuesExtractors::Scalar scalar(dim);
-        typename FunctionMap<dim>::type neumann_boundary;
-        KellyErrorEstimator<dim>::estimate (dof_handler_local,
-                                            QGauss<dim-1>(3),
-                                            neumann_boundary,
-                                            solution_local,
-                                            estimated_error_per_cell,
-                                            fe_local.component_mask(scalar));
+          FEValuesExtractors::Scalar scalar(dim);
+          typename FunctionMap<dim>::type neumann_boundary;
+          KellyErrorEstimator<dim>::estimate (dof_handler_local,
+                                              QGauss<dim-1>(3),
+                                              neumann_boundary,
+                                              solution_local,
+                                              estimated_error_per_cell,
+                                              fe_local.component_mask(scalar));
 
-        GridRefinement::refine_and_coarsen_fixed_number (triangulation,
-                                                         estimated_error_per_cell,
-                                                         0.3, 0.);
+          GridRefinement::refine_and_coarsen_fixed_number (triangulation,
+                                                           estimated_error_per_cell,
+                                                           0.3, 0.);
 
-        triangulation.execute_coarsening_and_refinement ();
+          triangulation.execute_coarsening_and_refinement ();
 
-        break;
-      }
+          break;
+        }
 
       default:
-      {
-        Assert (false, ExcNotImplemented());
-      }
+        {
+          Assert (false, ExcNotImplemented());
+        }
       }
-  }
+
+  // Just as in step-7, we set the boundary indicator of one of the faces to 1
+  // where we want to specify Neumann boundary conditions instead of Dirichlet
+  // conditions. Since we re-create the triangulation every time for global
+  // refinement, the flags are set in every refinement step, not just at the
+  // beginning.
+  typename Triangulation<dim>::cell_iterator
+    cell = triangulation.begin (),
+    endc = triangulation.end();
+  for (; cell!=endc; ++cell)
+    for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+      if ((std::fabs(cell->face(face)->center()(0) - (-1)) < 1e-12)
+          ||
+          (std::fabs(cell->face(face)->center()(1) - (-1)) < 1e-12))
+        cell->face(face)->set_boundary_indicator (1);
+}
 
 
 
index 43e7e9a2944963cdf5a1bb7a9b47e05886035891..082e98bb390d272a2e9a788fd2a77a08bf408e37 100644 (file)
@@ -219,33 +219,24 @@ class DataOutBase
 {
 public:
   /**
-   * Data structure describing a patch of
-   * data in <tt>dim</tt> space
+   * Data structure describing a patch of data in <tt>dim</tt> space
    * dimensions.
    *
    * A patch consists of the following data:
    * <ul>
    * <li>the corner #vertices,
-   * <li> the number
-   * #n_subdivisions of the number
-   * of cells the Patch has in each
-   * space direction,
-   * <li> the #data attached to
-   * each vertex, in the usual
+   * <li> the number #n_subdivisions of the number of cells the Patch
+   * has in each space direction,
+   * <li> the #data attached to each vertex, in the usual
    * lexicographic ordering,
    * <li> Information on #neighbors.
    * </ul>
    *
-   * See the general
-   * documentation of the
-   * <tt>DataOutBase</tt> class for more
-   * information on its contents and
-   * purposes.  In the case of two
-   * dimensions, the next picture ist an
-   * example of <tt>n_subdivision</tt> = 4
-   * because the number of (sub)cells
-   * within each patch is equal to
-   * <tt>2^dim</tt>.
+   * See the general documentation of the DataOutBase class for more
+   * information on its contents and purposes.  In the case of two
+   * dimensions, the next picture ist an example of
+   * <tt>n_subdivision</tt> = 4 because the number of (sub)cells
+   * within each patch is equal to <tt>2<sup>dim</sup></tt>.
    *
    * @ingroup output
    *
@@ -255,34 +246,23 @@ public:
   struct Patch
   {
     /**
-     * Make the <tt>spacedim</tt> template
-     * parameter available.
+     * Make the <tt>spacedim</tt> template parameter available.
      */
     static const unsigned int space_dim=spacedim;
 
     /**
-     * Corner points of a patch.
-     * Inner points are computed by
-     * a multilinear transform of
-     * the unit cell to the cell
-     * specified by these corner
-     * points. The order of points
-     * is the same as for cells
-     * in the triangulation.
+     * Corner points of a patch.  Inner points are computed by a
+     * multilinear transform of the unit cell to the cell specified by
+     * these corner points. The order of points is the same as for
+     * cells in the triangulation.
      */
     Point<spacedim> vertices[GeometryInfo<dim>::vertices_per_cell];
 
     /**
-     * Numbers of neighbors of a patch.
-     * OpenDX format requires
-     * neighbor information for
-     * advanced output. Here the
-     * neighborship relationship
-     * of patches is
-     * stored. During output,
-     * this must be transformed
-     * into neighborship of
-     * sub-grid cells.
+     * Numbers of neighbors of a patch.  OpenDX format requires
+     * neighbor information for advanced output. Here the neighborship
+     * relationship of patches is stored. During output, this must be
+     * transformed into neighborship of sub-grid cells.
      */
     unsigned int neighbors[dim > 0
                            ?
@@ -291,124 +271,77 @@ public:
                            1];
 
     /**
-     * Number of this
-     * patch. Since we are not
-     * sure patches are handled
-     * in the same order, always,
-     * we better store this.
+     * Number of this patch. Since we are not sure patches are handled
+     * in the same order, always, we better store this.
      */
     unsigned int patch_index;
 
     /**
-     * Number of subdivisions with
-     * which this patch is to be
-     * written. <tt>1</tt> means no
-     * subdivision, <tt>2</tt> means
-     * bisection, <tt>3</tt> trisection,
-     * etc.
+     * Number of subdivisions with which this patch is to be
+     * written. <tt>1</tt> means no subdivision, <tt>2</tt> means
+     * bisection, <tt>3</tt> trisection, etc.
      */
     unsigned int n_subdivisions;
 
     /**
-     * Data vectors. The format is
-     * as follows:
-     * <tt>data(i,.)</tt> denotes the data
-     * belonging to the <tt>i</tt>th data
-     * vector. <tt>data.n()</tt>
-     * therefore equals the number
-     * of output points; this
-     * number is <tt>(subdivisions+1)^{dim</tt>}.
-     * <tt>data.m()</tt> equals the number of
-     * data vectors.
+     * Data vectors. The format is as follows: <tt>data(i,.)</tt>
+     * denotes the data belonging to the <tt>i</tt>th data
+     * vector. <tt>data.n()</tt> therefore equals the number of output
+     * points; this number is <tt>(subdivisions+1)^{dim</tt>}.
+     * <tt>data.m()</tt> equals the number of data vectors.
      *
-     * Within each column,
-     * <tt>data(.,j)</tt> are the
-     * data values at the output
-     * point <tt>j</tt>, where
-     * <tt>j</tt> denotes the
-     * usual lexicographic
-     * ordering in deal.II. This
-     * is also the order of
-     * points as provided by the
-     * <tt>QIterated</tt> class
-     * when used with the
-     * <tt>QTrapez</tt> class as
-     * subquadrature.
+     * Within each column, <tt>data(.,j)</tt> are the data values at
+     * the output point <tt>j</tt>, where <tt>j</tt> denotes the usual
+     * lexicographic ordering in deal.II. This is also the order of
+     * points as provided by the <tt>QIterated</tt> class when used
+     * with the <tt>QTrapez</tt> class as subquadrature.
      *
-     * Since the number of data vectors
-     * is usually the same for all
-     * patches to be printed,
-     * <tt>data.size()</tt> should yield
-     * the same value for all patches
-     * provided. The exception are
-     * patches for which
-     * points_are_available are set,
-     * where the actual coordinates of
-     * the point are appended to the
-     * 'data' field, see the
-     * documentation of the
-     * points_are_available flag.
+     * Since the number of data vectors is usually the same for all
+     * patches to be printed, <tt>data.size()</tt> should yield the
+     * same value for all patches provided. The exception are patches
+     * for which points_are_available are set, where the actual
+     * coordinates of the point are appended to the 'data' field, see
+     * the documentation of the points_are_available flag.
      */
     Table<2,float> data;
 
     /**
-     * Bool flag indicating, whether the
-     * coordinates of the inner patch
-     * points are appended to the @p data
-     * table (@ true) or not (@ false),
-     * where the second is the standard and
-     * can be found for all cells in the
-     * interior of a domain.
+     * Bool flag indicating, whether the coordinates of the inner
+     * patch points are appended to the @p data table (@p true) or not
+     * (@p false), where the second is the standard and can be found
+     * for all cells in the interior of a domain.
      *
-     * On the boundary of a domain, patch
-     * points are evaluated using a
-     * Mapping and therefore have to be
-     * stored inside the patch, as the
-     * Mapping and the corresponding
-     * boundary information are no longer
-     * available later on when we
-     * actually write the patch out to an
-     * output stream.
+     * On the boundary of a domain, patch points are evaluated using a
+     * Mapping and therefore have to be stored inside the patch, as
+     * the Mapping and the corresponding boundary information are no
+     * longer available later on when we actually write the patch out
+     * to an output stream.
      */
     bool points_are_available;
 
     /**
-     * Default constructor. Sets
-     * <tt>n_subdivisions</tt> to one.
+     * Default constructor. Sets #n_subdivisions to one.
      */
     Patch ();
 
     /**
-     * Compare the present patch
-     * for equality with another
-     * one. This is used in a few
-     * of the automated tests in
-     * our testsuite.
+     * Compare the present patch for equality with another one. This
+     * is used in a few of the automated tests in our testsuite.
      */
     bool operator == (const Patch &patch) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
 
     /**
-     * Value to be used if this
-     * patch has no neighbor on
-     * one side.
+     * Value to be used if this patch has no neighbor on one side.
      */
     static const unsigned int no_neighbor = numbers::invalid_unsigned_int;
     /** @addtogroup Exceptions
@@ -426,47 +359,36 @@ public:
   };
 
   /**
-   * Flags controlling the details of
-   * output in OpenDX format.
+   * Flags controlling the details of output in OpenDX format.
    *
    * @ingroup output
    */
   struct DXFlags
   {
     /**
-     * Write neighbor
-     * information. This
-     * information is necessary
-     * for instance, if OpenDX is
-     * supposed to compute
-     * integral curves
-     * (streamlines). If it is
-     * not present, streamlines
-     * end at cell boundaries.
+     * Write neighbor information. This information is necessary for
+     * instance, if OpenDX is supposed to compute integral curves
+     * (streamlines). If it is not present, streamlines end at cell
+     * boundaries.
      */
     bool write_neighbors;
     /**
-     * Write integer values of
-     * the Triangulation in
-     * binary format.
+     * Write integer values of the Triangulation in binary format.
      */
     bool int_binary;
     /**
-     * Write coordinate vectors in
-     * binary format.
+     * Write coordinate vectors in binary format.
      */
     bool coordinates_binary;
 
     /**
-     * Write data vectors in
-     * binary format.
+     * Write data vectors in binary format.
      */
     bool data_binary;
 
     /**
-     * Write binary coordinate
-     * vectors as double (64 bit)
-     * numbers instead of float (32 bit).
+     * Write binary coordinate vectors as double (64 bit) numbers
+     * instead of float (32 bit).
      */
     bool data_double;
 
@@ -479,56 +401,40 @@ public:
              const bool data_binary = false);
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and set
+     * the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm);
 
     /**
-     * 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;
   };
 
   /**
-   * Flags controlling the details
-   * of output in UCD format for
-   * AVS.
+   * Flags controlling the details of output in UCD format for AVS.
    *
    * @ingroup output
    */
   struct UcdFlags
   {
     /**
-     * Write a comment at the
-     * beginning of the file
-     * stating the date of
-     * creation and some other
-     * data.  While this is
-     * supported by the UCD
-     * format and
-     * AVS, some other
-     * programs get confused by
-     * this, so the default is to
-     * not write a
-     * preamble. However, a
-     * preamble can be written
-     * using this flag.
+     * Write a comment at the beginning of the file stating the date
+     * of creation and some other data.  While this is supported by
+     * the UCD format and AVS, some other programs get confused by
+     * this, so the default is to not write a preamble. However, a
+     * preamble can be written using this flag.
      *
      * Default: <code>false</code>.
      */
@@ -540,45 +446,33 @@ public:
     UcdFlags (const bool write_preamble = false);
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and
+     * set the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm);
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Flags controlling the details of
-   * output in Gnuplot format. At
+   * Flags controlling the details of output in Gnuplot format. At
    * present no flags are implemented.
    *
    * @ingroup output
@@ -587,12 +481,9 @@ public:
   {
   private:
     /**
-     * Dummy entry to suppress compiler
-     * warnings when copying an empty
-     * structure. Remove this member
-     * when adding the first flag to
-     * this structure (and remove the
-     * <tt>private</tt> as well).
+     * Dummy entry to suppress compiler warnings when copying an empty
+     * structure. Remove this member when adding the first flag to
+     * this structure (and remove the <tt>private</tt> as well).
      */
     int dummy;
 
@@ -603,74 +494,56 @@ public:
     GnuplotFlags ();
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and set
+     * the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Flags controlling the details
-   * of output in Povray
-   * format. Several flags are
-   * implemented, see their
-   * respective documentation.
+   * Flags controlling the details of output in Povray format. Several
+   * flags are implemented, see their respective documentation.
    *
    * @ingroup output
    */
   struct PovrayFlags
   {
     /**
-     * Normal vector interpolation,
-     * if set to true
+     * Normal vector interpolation, if set to true
      *
      * default = false
      */
     bool smooth;
 
     /**
-     * Use bicubic patches (b-splines)
-     * instead of triangles.
+     * Use bicubic patches (b-splines) instead of triangles.
      *
      * default = false
      */
     bool bicubic_patch;
 
     /**
-     * include external "data.inc"
-     * with camera, light and
-     * texture definition for the
-     * scene.
+     * include external "data.inc" with camera, light and texture
+     * definition for the scene.
      *
      * default = false
      */
@@ -684,79 +557,59 @@ public:
                  const bool external_data = false);
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and
+     * set the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm);
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
 
   /**
-   * Flags controlling the details of
-   * output in encapsulated postscript
-   * format.
+   * Flags controlling the details of output in encapsulated
+   * postscript format.
    *
    * @ingroup output
    */
   struct EpsFlags
   {
     /**
-     * This denotes the number of the
-     * data vector which shall be used
-     * for generating the height
-     * information. By default, the
-     * first data vector is taken,
-     * i.e. <tt>height_vector==0</tt>, if
-     * there is any data vector. If there
-     * is no data vector, no height
+     * This denotes the number of the data vector which shall be used
+     * for generating the height information. By default, the first
+     * data vector is taken, i.e. <tt>height_vector==0</tt>, if there
+     * is any data vector. If there is no data vector, no height
      * information is generated.
      */
     unsigned int height_vector;
 
     /**
-     * Number of the vector which is
-     * to be taken to colorize cells.
-     * The same applies as for
-     * <tt>height_vector</tt>.
+     * Number of the vector which is to be taken to colorize cells.
+     * The same applies as for #height_vector.
      */
     unsigned int color_vector;
 
     /**
-     * Enum denoting the possibilities
-     * whether the scaling should be done
-     * such that the given <tt>size</tt> equals
-     * the width or the height of
-     * the resulting picture.
+     * Enum denoting the possibilities whether the scaling should be
+     * done such that the given <tt>size</tt> equals the width or the
+     * height of the resulting picture.
      */
     enum SizeType
     {
@@ -772,49 +625,34 @@ public:
     SizeType size_type;
 
     /**
-     * Width or height of the output
-     * as given in postscript units
-     * This usually is given by the
-     * strange unit 1/72 inch. Whether
-     * this is height or width is
-     * specified by the flag
-     * <tt>size_type</tt>.
+     * Width or height of the output as given in postscript units This
+     * usually is given by the strange unit 1/72 inch. Whether this is
+     * height or width is specified by the flag <tt>size_type</tt>.
      *
-     * Default is 300, which represents
-     * a size of roughly 10 cm.
+     * Default is 300, which represents a size of roughly 10 cm.
      */
     unsigned int size;
 
     /**
-     * Width of a line in postscript
-     * units. Default is 0.5.
+     * Width of a line in postscript units. Default is 0.5.
      */
     double line_width;
 
     /**
-     * Angle of the line origin-viewer
-     * against the z-axis in degrees.
+     * Angle of the line origin-viewer against the z-axis in degrees.
      *
-     * Default is the Gnuplot-default
-     * of 60.
+     * Default is the Gnuplot-default of 60.
      */
     double azimut_angle;
 
     /**
-     * Angle by which the viewers
-     * position projected onto the
-     * x-y-plane is rotated around
-     * the z-axis, in positive sense
-     * when viewed from above. The
-     * unit are degrees, and zero
-     * equals a position above or below
-     * the negative y-axis.
+     * Angle by which the viewers position projected onto the
+     * x-y-plane is rotated around the z-axis, in positive sense when
+     * viewed from above. The unit are degrees, and zero equals a
+     * position above or below the negative y-axis.
      *
-     * Default is the
-     * Gnuplot-default of 30.
-     * An example of a
-     * Gnuplot-default of 0 is
-     * the following:
+     * Default is the Gnuplot-default of 30.  An example of a
+     * Gnuplot-default of 0 is the following:
      *
      * @verbatim
      *
@@ -833,75 +671,58 @@ public:
     double turn_angle;
 
     /**
-     * Factor by which the z-axis is to
-     * be stretched as compared to the
-     * x- and y-axes. This is to compensate
-     * for the different sizes that
-     * coordinate and solution values may
-     * have and to prevent that the plot
-     * looks to much out-of-place (no
-     * elevation at all if solution values
-     * are much smaller than coordinate
-     * values, or the common "extremely
-     * mountainous area" in the opposite
-     * case.
+     * Factor by which the z-axis is to be stretched as compared to
+     * the x- and y-axes. This is to compensate for the different
+     * sizes that coordinate and solution values may have and to
+     * prevent that the plot looks to much out-of-place (no elevation
+     * at all if solution values are much smaller than coordinate
+     * values, or the common "extremely mountainous area" in the
+     * opposite case.
      *
      * Default is <tt>1.0</tt>.
      */
     double z_scaling;
 
     /**
-     * Flag the determines whether the
-     * lines bounding the cells (or the
-     * parts of each patch) are to be
-     * plotted.
+     * Flag the determines whether the lines bounding the cells (or
+     * the parts of each patch) are to be plotted.
      *
      * Default: <tt>true</tt>.
      */
     bool   draw_mesh;
 
     /**
-     * Flag whether to fill the regions
-     * between the lines bounding the cells
-     * or not. If not, no hidden line removal
-     * is performed, which in this crude
-     * implementation is done through
-     * writing the cells in a back-to-front
-     * order, thereby hiding the cells in
-     * the background by cells in the
-     * foreground.
+     * Flag whether to fill the regions between the lines bounding the
+     * cells or not. If not, no hidden line removal is performed,
+     * which in this crude implementation is done through writing the
+     * cells in a back-to-front order, thereby hiding the cells in the
+     * background by cells in the foreground.
      *
-     * If this flag is <tt>false</tt> and <tt>draw_mesh</tt>
-     * is <tt>false</tt> as well, nothing will be
-     * printed.
+     * If this flag is <tt>false</tt> and #draw_mesh is <tt>false</tt>
+     * as well, nothing will be printed.
      *
-     * If this flag is <tt>true</tt>, then the cells
-     * will be drawn either colored by one
-     * of the data sets (if <tt>shade_cells</tt> is
-     * <tt>true</tt>), or pure white (if
-     * <tt>shade_cells</tt> is false or if there are
-     * no data sets).
+     * If this flag is <tt>true</tt>, then the cells will be drawn
+     * either colored by one of the data sets (if #shade_cells is
+     * <tt>true</tt>), or pure white (if #shade_cells is false or if
+     * there are no data sets).
      *
      * Default is <tt>true</tt>.
      */
     bool   draw_cells;
 
     /**
-     * Flag to determine whether the cells
-     * shall be colorized by the data
-     * set denoted by <tt>color_vector</tt>, or
-     * simply be painted in white. This
-     * flag only makes sense if
-     * <tt>draw_cells==true</tt>. Colorization is
-     * done through the <tt>color_function</tt>.
+     * Flag to determine whether the cells shall be colorized by the
+     * data set denoted by #color_vector, or simply be painted in
+     * white. This flag only makes sense if
+     * <tt>#draw_cells==true</tt>. Colorization is done through
+     * #color_function.
      *
      * Default is <tt>true</tt>.
      */
     bool   shade_cells;
 
     /**
-     * Structure keeping the three color
-     * values in the RGB system.
+     * Structure keeping the three color values in the RGB system.
      */
     struct RgbValues
     {
@@ -910,52 +731,39 @@ public:
       float blue;
 
       /**
-       * Return <tt>true</tt> if the
-       * color represented by
-       * the three color values
-       * is a grey scale,
-       * i.e. all components
-       * are equal.
+       * Return <tt>true</tt> if the color represented by the three
+       * color values is a grey scale, i.e. all components are equal.
        */
       bool is_grey () const;
     };
 
     /**
-     * Definition of a function pointer
-     * type taking a value and returning
-     * a triple of color values in RGB
-     * values.
+     * Definition of a function pointer type taking a value and
+     * returning a triple of color values in RGB values.
      *
-     * Besides the actual value by which
-     * the color is to be computed, min
-     * and max values of the data to
-     * be colorized are given as well.
+     * Besides the actual value by which the color is to be computed,
+     * min and max values of the data to be colorized are given as
+     * well.
      */
     typedef RgbValues (*ColorFunction) (const double value,
                                         const double min_value,
                                         const double max_value);
 
     /**
-     * This is a pointer to the function
-     * which is used to colorize the cells.
-     * By default, it points to the
-     * static function <tt>default_color_function</tt>
-     * which is a member of this class.
+     * This is a pointer to the function which is used to colorize the
+     * cells.  By default, it points to the static function
+     * default_color_function() which is a member of this class.
      */
     ColorFunction color_function;
 
 
     /**
-     * Default colorization function. This
-     * one does what one usually wants:
-     * It shifts colors from black (lowest
-     * value) through blue, green and red
-     * to white (highest value). For the
-     * exact defition of the color scale
-     * refer to the implementation.
+     * Default colorization function. This one does what one usually
+     * wants: It shifts colors from black (lowest value) through blue,
+     * green and red to white (highest value). For the exact defition
+     * of the color scale refer to the implementation.
      *
-     * This function was originally written
-     * by Stefan Nauber.
+     * This function was originally written by Stefan Nauber.
      */
     static RgbValues
     default_color_function (const double value,
@@ -963,12 +771,9 @@ public:
                             const double max_value);
 
     /**
-     * This is an alternative color
-     * function producing a grey scale
-     * between black (lowest values)
-     * and white (highest values). You
-     * may use it by setting the
-     * <tt>color_function</tt> variable to the
+     * This is an alternative color function producing a grey scale
+     * between black (lowest values) and white (highest values). You
+     * may use it by setting the #color_function variable to the
      * address of this function.
      */
     static RgbValues
@@ -977,18 +782,11 @@ public:
                                const double max_value);
 
     /**
-     * This is one more
-     * alternative color function
-     * producing a grey scale
-     * between white (lowest
-     * values) and black (highest
-     * values), i.e. the scale is
-     * reversed to the previous
-     * one. You may use it by
-     * setting the
-     * <tt>color_function</tt>
-     * variable to the address of
-     * this function.
+     * This is one more alternative color function producing a grey
+     * scale between white (lowest values) and black (highest values),
+     * i.e. the scale is reversed to the previous one. You may use it
+     * by setting the #color_function variable to the address of this
+     * function.
      */
     static RgbValues
     reverse_grey_scale_color_function (const double value,
@@ -1012,51 +810,37 @@ public:
               const ColorFunction color_function= &default_color_function);
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      *
-     * For coloring, only the color
-     * functions declared in this
-     * class are offered.
+     * For coloring, only the color functions declared in this class
+     * are offered.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and set
+     * the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm);
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Flags controlling the details
-   * of output in GMV
-   * format. At present no flags
-   * are implemented.
+   * Flags controlling the details of output in GMV format. At present
+   * no flags are implemented.
    *
    * @ingroup output
    */
@@ -1064,12 +848,9 @@ public:
   {
   private:
     /**
-     * Dummy entry to suppress compiler
-     * warnings when copying an empty
-     * structure. Remove this member
-     * when adding the first flag to
-     * this structure (and remove the
-     * <tt>private</tt> as well).
+     * Dummy entry to suppress compiler warnings when copying an empty
+     * structure. Remove this member when adding the first flag to
+     * this structure (and remove the <tt>private</tt> as well).
      */
     int dummy;
 
@@ -1080,46 +861,33 @@ public:
     GmvFlags ();
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and set
+     * the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Flags controlling the details
-   * of output in
-   * Tecplot format.
+   * Flags controlling the details of output in Tecplot format.
    *
    * @ingroup output
    */
@@ -1129,20 +897,16 @@ public:
   public:
 
     /**
-     * This variable is needed to hold the
-     * output file name when using the
-     * Tecplot API to write binary files.
-     * If the user doesn't set the file
-     * name with this variable only
-     * ASCII Tecplot output will be
-     * produced.
+     * This variable is needed to hold the output file name when using
+     * the Tecplot API to write binary files.  If the user doesn't set
+     * the file name with this variable only ASCII Tecplot output will
+     * be produced.
      */
     const char *tecplot_binary_file_name;
 
     /**
-     * Tecplot allows to assign
-     * names to zones. This
-     * variable stores this name.
+     * Tecplot allows to assign names to zones. This variable stores
+     * this name.
      */
     const char *zone_name;
 
@@ -1153,46 +917,33 @@ public:
                   const char *zone_name = NULL);
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and set
+     * the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Flags controlling the details
-   * of output in VTK
-   * format.
+   * Flags controlling the details of output in VTK format.
    *
    * @ingroup output
    */
@@ -1200,32 +951,33 @@ public:
   {
   public:
     /**
-     * The time of the time step if this file is part of a
-     * time dependent simulation.
+     * The time of the time step if this file is part of a time
+     * dependent simulation.
      *
-     * The value of this variable is written into the output file according
-     * to the instructions provided in
+     * The value of this variable is written into the output file
+     * according to the instructions provided in
      * http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
-     * unless it is at its default value of std::numeric_limits<double>::min().
+     * unless it is at its default value of
+     * std::numeric_limits<double>::min().
      */
     double time;
 
     /**
-     * The number of the time step if this file is part of a
-     * time dependent simulation, or the cycle within a nonlinear or other
+     * The number of the time step if this file is part of a time
+     * dependent simulation, or the cycle within a nonlinear or other
      * iteration.
      *
-     * The value of this variable is written into the output file according
-     * to the instructions provided in
+     * The value of this variable is written into the output file
+     * according to the instructions provided in
      * http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
-     * unless it is at its default value of std::numeric_limits<unsigned int>::min().
+     * unless it is at its default value of
+     * std::numeric_limits<unsigned int>::min().
      */
     unsigned int cycle;
 
    /**
-     * Flag to determine whether the current
-     * date and time shall be printed as a comment
-     * in the file's second line.
+     * Flag to determine whether the current date and time shall be
+     * printed as a comment in the file's second line.
      *
      * Default is <tt>true</tt>.
      */
@@ -1239,9 +991,8 @@ public:
               const bool print_date_and_time = true);
 
     /**
-     * Declare the flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare the flags with name and type as offered by this class,
+     * for use in input files.
      *
      * Unlike the flags in many of the other classes similar to this one, we do
      * not actually declare parameters for the #cycle and #time member variables
@@ -1254,31 +1005,21 @@ public:
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and
+     * set the flags for this output format accordingly.
      *
-     * The flags thus obtained overwrite
-     * all previous contents of this object.
+     * The flags thus obtained overwrite all previous contents of this
+     * object.
      */
     void parse_parameters (const ParameterHandler &prm) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
@@ -1290,37 +1031,45 @@ public:
   struct SvgFlags
   {
   public:
-    /**
-     * This denotes the number of the
-     * data vector which shall be used
-     * for generating the height
-     * information. By default, the
-     * first data vector is taken,
-     * i.e. <tt>height_vector==0</tt>, if
-     * there is any data vector. If there
-     * is no data vector, no height
+                                      /**
+                                       * Height of the image in SVG
+                                       * units. Default value is 4000.
+                                       */
+      unsigned int height;
+      
+                                      /**
+                                       * Width of the image in SVG
+    units. If left zero, the width is computed from the height.
+                                      */
+      unsigned int width;
+      
+    /**
+     * This denotes the number of the data vector which shall be used
+     * for generating the height information. By default, the first
+     * data vector is taken, i.e. <tt>#height_vector==0</tt>, if there
+     * is any data vector. If there is no data vector, no height
      * information is generated.
      */
-    unsigned int height_vector;
-
-    /*
+      unsigned int height_vector;
+      
+    /**
      * Angles for the perspective view
      */
     int azimuth_angle, polar_angle;
 
     unsigned int line_thickness;
 
-    /*
+                                      /**
      * Draw a margin of 5% around the plotted area
      */
     bool margin;
 
-    /*
+                                      /**
      * Draw a colorbar encoding the cell coloring
      */
     bool draw_colorbar;
 
-    /*
+                                      /**
      * Constructor.
      */
     SvgFlags(const unsigned int height_vector = 0,
@@ -1331,20 +1080,12 @@ public:
              const bool draw_colorbar = true);
 
     /**
-     * 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.
+     * 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.
     */
     std::size_t memory_consumption () const;
 
@@ -1354,38 +1095,26 @@ public:
 
 
   /**
-   * Flags controlling the details
-   * of output in deal.II
-   * intermediate format. At
-   * present no flags are
-   * implemented.
+   * Flags controlling the details of output in deal.II intermediate
+   * format. At present no flags are implemented.
    *
    * @ingroup output
    */
   struct Deal_II_IntermediateFlags
   {
     /**
-     * An indicator of the
-     * currect file format
-     * version used to write
-     * intermediate format. We do
-     * not attempt to be backward
-     * compatible, so this number
-     * is used only to verify
-     * that the format we are
-     * writing is what the
-     * current readers and
-     * writers understand.
+     * An indicator of the currect file format version used to write
+     * intermediate format. We do not attempt to be backward
+     * compatible, so this number is used only to verify that the
+     * format we are writing is what the current readers and writers
+     * understand.
      */
     static const unsigned int format_version = 3;
   private:
     /**
-     * Dummy entry to suppress compiler
-     * warnings when copying an empty
-     * structure. Remove this member
-     * when adding the first flag to
-     * this structure (and remove the
-     * <tt>private</tt> as well).
+     * Dummy entry to suppress compiler warnings when copying an empty
+     * structure. Remove this member when adding the first flag to
+     * this structure (and remove the <tt>private</tt> as well).
      */
     int dummy;
 
@@ -1396,17 +1125,14 @@ public:
     Deal_II_IntermediateFlags ();
 
     /**
-     * Declare all flags with name
-     * and type as offered by this
-     * class, for use in input files.
+     * Declare all flags with name and type as offered by this class,
+     * for use in input files.
      */
     static void declare_parameters (ParameterHandler &prm);
 
     /**
-     * Read the parameters declared in
-     * <tt>declare_parameters</tt> and set the
-     * flags for this output format
-     * accordingly.
+     * Read the parameters declared in declare_parameters() and
+     * set the flags for this output format accordingly.
      *
      * The flags thus obtained overwrite
      * all previous contents of this object.
@@ -1414,34 +1140,24 @@ public:
     void parse_parameters (const ParameterHandler &prm) const;
 
     /**
-     * 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.
+     * 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.
      */
     std::size_t memory_consumption () const;
   };
 
   /**
-   * Provide a data type specifying
-   * the presently supported output
+   * Provide a data type specifying the presently supported output
    * formats.
    */
   enum OutputFormat
   {
     /**
-     * Use the format already
-     * stored in the object.
+     * Use the format already stored in the object.
      */
     default_format,
     /**
@@ -1453,24 +1169,19 @@ public:
      */
     dx,
     /**
-     * Output in the UCD format
-     * for AVS.
+     * Output in the UCD format for AVS.
      */
     ucd,
     /**
-     * Output for the
-     * Gnuplot tool.
+     * Output for the Gnuplot tool.
      */
     gnuplot,
     /**
-     * Output for the
-     * Povray
-     * raytracer.
+     * Output for the Povray raytracer.
      */
     povray,
     /**
-     * Output in encapsulated
-     * PostScript.
+     * Output in encapsulated PostScript.
      */
     eps,
     /**
@@ -1478,56 +1189,46 @@ public:
      */
     gmv,
     /**
-     * Output for
-     * Tecplot in text
-     * format.
+     * Output for Tecplot in text format.
      */
 
     tecplot,
     /**
-     * Output for
-     * Tecplot in
-     * binary format. Faster
-     * and smaller than text
-     * format.
+     * Output for Tecplot in binary format. Faster and smaller than
+     * text format.
      */
     tecplot_binary,
 
     /**
-     * Output in
-     * VTK format.
+     * Output in VTK format.
      */
     vtk,
 
     /**
-     * Output in
-     * VTK format.
+     * Output in VTK format.
      */
     vtu,
 
     /**
-     * Output in
-     * SVG format.
+     * Output in SVG format.
      */
     svg,
 
     /**
-     * Output in deal.II
-     * intermediate format.
+     * Output in deal.II intermediate format.
      */
     deal_II_intermediate,
 
     /**
-     * Output in
-     * HDF5 format.
+     * Output in HDF5 format.
      */
     hdf5
   };
 
 
   /**
-   * Write the given list of patches to the output stream in
-   * OpenDX format.
+   * Write the given list of patches to the output stream in OpenDX
+   * format.
    *
    * Since OpenDX uses some kind of visual data flow oriented
    * programming language, some of these programs are provided in
@@ -1544,15 +1245,15 @@ public:
    * Write the given list of patches to the output stream in eps format.
    *
    * Output in this format circumvents the use of auxiliary graphic
-   * programs converting some output format into a graphics format. This
-   * has the advantage that output is easy and fast, and the
-   * disadvantage that you have to give a whole bunch of parameters
-   * which determine the direction of sight, the mode of colorization,
-   * the scaling of the height axis, etc. (Of course, all these
-   * parameters have reasonable default values, which you may want to
-   * change from time to time.) At present, this format only supports
-   * output for two-dimensional data, with values in the third direction
-   * taken from a data vector.
+   * programs converting some output format into a graphics
+   * format. This has the advantage that output is easy and fast, and
+   * the disadvantage that you have to give a whole bunch of
+   * parameters which determine the direction of sight, the mode of
+   * colorization, the scaling of the height axis, etc. (Of course,
+   * all these parameters have reasonable default values, which you
+   * may want to change from time to time.) At present, this format
+   * only supports output for two-dimensional data, with values in the
+   * third direction taken from a data vector.
    *
    * Basically, output consists of the mesh and the cells in between
    * them. You can draw either of these, or both, or none if you are
@@ -1982,71 +1683,49 @@ public:
     MPI_Comm comm);
 
   /**
-   * Given an input stream that contains
-   * data written by
-   * write_deal_II_intermediate, determine
-   * the <tt>dim</tt> and <tt>spacedim</tt>
-   * template parameters with which that
-   * function was called, and return them
-   * as a pair of values.
+   * Given an input stream that contains data written by
+   * write_deal_II_intermediate(), determine the <tt>dim</tt> and
+   * <tt>spacedim</tt> template parameters with which that function
+   * was called, and return them as a pair of values.
    *
-   * Note that this function eats a number
-   * of elements at the present position of
-   * the stream, and therefore alters
-   * it. In order to read from it using,
-   * for example, the DataOutReader class,
-   * you may wish to either reset the
-   * stream to its previous position, or
-   * close and reopen it.
+   * Note that this function eats a number of elements at the present
+   * position of the stream, and therefore alters it. In order to read
+   * from it using, for example, the DataOutReader class, you may wish
+   * 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);
 
   /**
-   * Return the <tt>OutputFormat</tt>
-   * value corresponding to the
-   * given 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 implemented output
-   * format without the need to
-   * extend the program's parser
-   * each time a new format is
-   * implemented.
-   *
-   * To get a list of presently
-   * available format names,
-   * e.g. to give it to the
-   * ParameterHandler class,
-   * use the function
+   * Return the OutputFormat value corresponding to the given
+   * 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
+   * implemented output format without the need to extend the
+   * program's parser each time a new format is implemented.
+   *
+   * To get a list of presently available format names, e.g. to give
+   * it to the ParameterHandler class, use the function
    * get_output_format_names().
    */
   static 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
+   * 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 ();
 
   /**
-   * Provide a function which tells us which
-   * suffix a file with a given output format
-   * usually has. At present the following
-   * formats are defined:
+   * Provide a function which tells us which suffix a file with a
+   * given output format usually has. At present the following formats
+   * are defined:
    * <ul>
    * <li> <tt>dx</tt>: <tt>.dx</tt>
    * <li> <tt>ucd</tt>: <tt>.inp</tt>
@@ -2065,20 +1744,12 @@ public:
   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.
+   * 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 ();
 
@@ -2093,9 +1764,7 @@ public:
                   << "The number of points in this data set is " << arg1
                   << ", but we expected " << arg2 << " in each space direction.");
   /**
-   * An output function did not
-   * receive any patches for
-   * writing.
+   * An output function did not receive any patches for writing.
    */
   DeclException0 (ExcNoPatches);
   /**
@@ -2113,24 +1782,21 @@ public:
   //@}
 private:
   /**
-   * Write the coordinates of nodes
-   * in the desired format.
+   * 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.
+   * 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.
+   * Write data in the desired format.
    */
   template <int dim, int spacedim, class STREAM>
   static void write_data (const std::vector<Patch<dim,spacedim> > &patches,
@@ -2155,8 +1821,8 @@ private:
                                     Point<3> camera_horizontal,
                                     float camera_focus);
   /**
-   * Function to compute the gradient parameters for
-   * a triangle with given values for the vertices.
+   * Function to compute the gradient parameters for a triangle with
+   * given values for the vertices.
    *
    * Used for svg output.
    */
@@ -2165,8 +1831,8 @@ private:
   /**
    * 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.
+   * three-dimensional space (two coordinates, one height value) to
+   * the direction of sight.
    */
   class SvgCell
   {
@@ -2181,10 +1847,8 @@ private:
     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.
+     * 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;
 
@@ -2197,21 +1861,17 @@ private:
     Point<2> projected_center;
 
     /**
-     * Comparison operator for
-     * sorting.
+     * 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 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
   {
@@ -2223,48 +1883,33 @@ private:
     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.
+     * 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.
+     * 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.
+     * Comparison operator for sorting.
      */
     bool operator < (const EpsCell2d &) const;
   };
 
 
   /**
-   * This is a helper function for
-   * the <tt>write_gmv</tt>
-   * 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.
+   * 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.
+   * 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
@@ -2286,9 +1931,9 @@ private:
  *
  * This class is thought as a base class to classes actually
  * generating data for output. It has two abstract virtual functions,
- * <tt>get_patches</tt> and <tt>get_dataset_names</tt> which are to produce the data
- * which is actually needed. These are the only functions that need to
- * be overloaded by a derived class.  In additional to that, it has a
+ * get_patches() and get_dataset_names() produce the data which is
+ * actually needed. These are the only functions that need to be
+ * overloaded by a derived class.  In additional to that, it has a
  * function for each output format supported by the underlying base
  * class which gets the output data using these two virtual functions
  * and passes them to the raw output functions.
@@ -2653,8 +2298,8 @@ public:
    * @endcode
    *
    * @note See DataOutBase::write_vtu or
-   * DataOutInterface::write_pvtu_record for
-   * writing solutions at each timestep.
+   * DataOutInterface::write_pvtu_record for writing solutions at each
+   * timestep.
    *
    * @note The second element of each pair, i.e., the file in which
    * the graphical data for each time is stored, may itself be again
@@ -2668,18 +2313,12 @@ public:
                          const std::vector<std::pair<double,std::string> >  &times_and_names) const;
 
   /**
-   * This function is the exact
-   * equivalent of the
-   * write_pvtu_record() function
-   * but for the VisIt
-   * visualization program. See
-   * there for the purpose of this
-   * function.
+   * This function is the exact equivalent of the write_pvtu_record()
+   * function but for the VisIt visualization program. See there for
+   * the purpose of this function.
    *
-   * This function is documented
-   * in the "Creating a master file
-   * for parallel" section (section 5.7)
-   * of the "Getting data into VisIt"
+   * This function is documented in the "Creating a master file for
+   * parallel" section (section 5.7) of the "Getting data into VisIt"
    * report that can be found here:
    * https://wci.llnl.gov/codes/visit/2.0.0/GettingDataIntoVisIt2.0.0.pdf
    */
@@ -2687,32 +2326,21 @@ public:
                            const std::vector<std::string> &piece_names) const;
 
   /**
-   * Obtain data through get_patches()
-   * and write it to <tt>out</tt>
-   * in SVG format. See
-   * DataOutBase::write_svg.
+   * Obtain data through get_patches() and write it to <tt>out</tt> in
+   * SVG format. See DataOutBase::write_svg.
    */
   void write_svg(std::ostream &out) const;
 
   /**
-   * Obtain data through get_patches()
-   * and write it to <tt>out</tt>
-   * in deal.II intermediate
-   * format. See
+   * Obtain data through get_patches() and write it to <tt>out</tt> in
+   * deal.II intermediate format. See
    * DataOutBase::write_deal_II_intermediate.
    *
-   * Note that the intermediate
-   * format is what its name
-   * suggests: a direct
-   * representation of internal
-   * data. It isn't standardized
-   * and will change whenever we
-   * change our internal
-   * representation. You can only
-   * expect to process files
-   * written in this format using
-   * the same version of deal.II
-   * that was used for writing.
+   * Note that the intermediate format is what its name suggests: a
+   * direct representation of internal data. It isn't standardized and
+   * will change whenever we change our internal representation. You
+   * can only expect to process files written in this format using the
+   * same version of deal.II that was used for writing.
    */
   void write_deal_II_intermediate (std::ostream &out) const;
 
@@ -2743,211 +2371,147 @@ public:
               const OutputFormat  output_format = default_format) const;
 
   /**
-   * Set the default format. The
-   * value set here is used
-   * anytime, output for format
-   * <tt>default_format</tt> is
-   * requested.
+   * 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);
 
   /**
-   * Set the flags to be used for
-   * output in OpenDX format.
+   * Set the flags to be used for output in OpenDX format.
    */
   void set_flags (const DXFlags &dx_flags);
 
   /**
-   * Set the flags to be used for
-   * output in UCD format.
+   * Set the flags to be used for output in UCD format.
    */
   void set_flags (const UcdFlags &ucd_flags);
 
   /**
-   * Set the flags to be used for
-   * output in GNUPLOT format.
+   * Set the flags to be used for output in GNUPLOT format.
    */
   void set_flags (const GnuplotFlags &gnuplot_flags);
 
   /**
-   * Set the flags to be used for
-   * output in POVRAY format.
+   * Set the flags to be used for output in POVRAY format.
    */
   void set_flags (const PovrayFlags &povray_flags);
 
   /**
-   * Set the flags to be used for
-   * output in EPS output.
+   * Set the flags to be used for output in EPS output.
    */
   void set_flags (const EpsFlags &eps_flags);
 
   /**
-   * Set the flags to be used for
-   * output in GMV format.
+   * Set the flags to be used for output in GMV format.
    */
   void set_flags (const GmvFlags &gmv_flags);
 
   /**
-   * Set the flags to be used for
-   * output in Tecplot format.
+   * Set the flags to be used for output in Tecplot format.
    */
   void set_flags (const TecplotFlags &tecplot_flags);
 
   /**
-   * Set the flags to be used for
-   * output in VTK format.
+   * Set the flags to be used for output in VTK format.
    */
   void set_flags (const VtkFlags &vtk_flags);
 
   /**
-   * Set the flags to be used for
-   * output in SVG format.
+   * Set the flags to be used for output in SVG format.
    */
   void set_flags (const SvgFlags &svg_flags);
 
   /**
-   * Set the flags to be used for output in
-   * deal.II intermediate format.
+   * Set the flags to be used for output in deal.II intermediate
+   * format.
    */
   void set_flags (const Deal_II_IntermediateFlags &deal_II_intermediate_flags);
 
   /**
-   * A function that returns the same
-   * string as the respective function in
-   * the base class does; the only
-   * exception being that if the parameter
-   * is omitted, then the value for the
-   * present default format is returned,
-   * i.e. the correct suffix for the format
-   * that was set through
-   * set_default_format() or
-   * parse_parameters() before calling this
-   * function.
+   * A function that returns the same string as the respective
+   * function in the base class does; the only exception being that if
+   * the parameter is omitted, then the value for the present default
+   * format is returned, i.e. the correct suffix for the format that
+   * was set through set_default_format() or parse_parameters() before
+   * calling this function.
    */
   std::string
   default_suffix (const OutputFormat output_format = default_format) const;
 
   /**
-   * Declare parameters for all
-   * output formats by declaring
-   * subsections within the
-   * parameter file for each output
-   * format and call the respective
-   * <tt>declare_parameters</tt>
-   * functions of the flag classes
-   * for each output format.
-   *
-   * Some of the declared
-   * subsections may not contain
-   * entries, if the respective
-   * format does not export any
-   * flags.
-   *
-   * Note that the top-level
-   * parameters denoting the number
-   * of subdivisions per patch and
-   * the output format are not
-   * declared, since they are only
-   * passed to virtual functions
-   * and are not stored inside
-   * objects of this type. You have
-   * to declare them yourself.
+   * Declare parameters for all output formats by declaring
+   * subsections within the parameter file for each output format and
+   * call the respective <tt>declare_parameters</tt> functions of the
+   * flag classes for each output format.
+   *
+   * Some of the declared subsections may not contain entries, if the
+   * respective format does not export any flags.
+   *
+   * Note that the top-level parameters denoting the number of
+   * subdivisions per patch and the output format are not declared,
+   * since they are only passed to virtual functions and are not
+   * stored inside objects of this type. You have to declare them
+   * yourself.
    */
   static void declare_parameters (ParameterHandler &prm);
 
   /**
-   * Read the parameters declared
-   * in <tt>declare_parameters</tt> and
-   * set the flags for the output
-   * formats accordingly.
+   * Read the parameters declared in declare_parameters() and
+   * set the flags for the output formats accordingly.
    *
-   * The flags thus obtained
-   * overwrite all previous
-   * contents of the flag objects
-   * as default-constructed or set
-   * by the set_flags() function.
+   * The flags thus obtained overwrite all previous contents of the
+   * flag objects as default-constructed or set by the set_flags()
+   * function.
    */
   void parse_parameters (ParameterHandler &prm);
 
   /**
-   * 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.
+   * 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.
    */
   std::size_t memory_consumption () const;
 
 protected:
   /**
-   * This is the abstract function
-   * through which derived classes
-   * propagate preprocessed data in
-   * the form of Patch
-   * structures (declared in the
-   * base class DataOutBase) to
-   * the actual output
-   * function. You need to overload
-   * this function to allow the
-   * output functions to know what
-   * they shall print.
+   * This is the abstract function through which derived classes
+   * propagate preprocessed data in the form of Patch structures
+   * (declared in the base class DataOutBase) to the actual output
+   * function. You need to overload this function to allow the output
+   * functions to know what they shall print.
    */
   virtual
   const std::vector<typename DataOutBase::Patch<dim,spacedim> > &
   get_patches () const = 0;
 
   /**
-   * Abstract virtual function
-   * through which the names of
-   * data sets are obtained by the
-   * output functions of the base
-   * class.
+   * Abstract virtual function through which the names of data sets
+   * are obtained by the output functions of the base class.
    */
   virtual
   std::vector<std::string>
   get_dataset_names () const = 0;
 
   /**
-   * This functions returns
-   * information about how the
-   * individual components of
-   * output files that consist of
-   * more than one data set are to
-   * be interpreted.
-   *
-   * It returns a list of index
-   * pairs and corresponding name
-   * indicating which components of
-   * the output are to be
-   * considered vector-valued
-   * rather than just a collection
-   * of scalar data. The index
-   * pairs are inclusive; for
-   * example, if we have a Stokes
-   * problem in 2d with components
-   * (u,v,p), then the
-   * corresponding vector data
-   * range should be (0,1), and the
-   * returned list would consist of
-   * only a single element with a
-   * tuple such as (0,1,"velocity").
-   *
-   * Since some of the derived
-   * classes do not know about
-   * vector data, this function has
-   * a default implementation that
-   * simply returns an empty
-   * string, meaning that all data
-   * is to be considered a
+   * This functions returns information about how the individual
+   * components of output files that consist of more than one data set
+   * are to be interpreted.
+   *
+   * It returns a list of index pairs and corresponding name
+   * indicating which components of the output are to be considered
+   * vector-valued rather than just a collection of scalar data. The
+   * index pairs are inclusive; for example, if we have a Stokes
+   * problem in 2d with components (u,v,p), then the corresponding
+   * vector data range should be (0,1), and the returned list would
+   * consist of only a single element with a tuple such as
+   * (0,1,"velocity").
+   *
+   * Since some of the derived classes do not know about vector data,
+   * this function has a default implementation that simply returns an
+   * empty string, meaning that all data is to be considered a
    * collection of scalar fields.
    */
   virtual
@@ -2955,108 +2519,83 @@ protected:
   get_vector_data_ranges () const;
 
   /**
-   * The default number of
-   * subdivisions for patches. This
-   * is filled by parse_parameters()
-   * and should be obeyed by
-   * build_patches() in derived
-   * classes.
+   * The default number of subdivisions for patches. This is filled by
+   * parse_parameters() and should be obeyed by build_patches() in
+   * derived classes.
    */
   unsigned int default_subdivisions;
 
 private:
   /**
-   * Standard output format.  Use
-   * this format, if output format
-   * default_format is
-   * requested. It can be changed
-   * by the <tt>set_format</tt> function
-   * or in a parameter file.
+   * Standard output format.  Use this format, if output format
+   * default_format is requested. It can be changed by the
+   * <tt>set_format</tt> function or in a parameter file.
    */
   OutputFormat default_fmt;
 
   /**
-   * Flags to be used upon output
-   * of OpenDX data. Can be changed by
-   * using the <tt>set_flags</tt>
-   * function.
+   * Flags to be used upon output of OpenDX data. Can be changed by
+   * using the <tt>set_flags</tt> function.
    */
   DXFlags     dx_flags;
 
   /**
-   * Flags to be used upon output
-   * of UCD data. Can be changed by
-   * using the <tt>set_flags</tt>
-   * function.
+   * Flags to be used upon output of UCD data. Can be changed by using
+   * the <tt>set_flags</tt> function.
    */
   UcdFlags     ucd_flags;
 
   /**
-   * Flags to be used upon output
-   * of GNUPLOT data. Can be
-   * changed by using the
-   * <tt>set_flags</tt> function.
+   * Flags to be used upon output of GNUPLOT data. Can be changed by
+   * using the <tt>set_flags</tt> function.
    */
   GnuplotFlags gnuplot_flags;
 
   /**
-   * Flags to be used upon output
-   * of POVRAY data. Can be changed
-   * by using the <tt>set_flags</tt>
-   * function.
+   * Flags to be used upon output of POVRAY data. Can be changed by
+   * using the <tt>set_flags</tt> function.
    */
   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>
+   * 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;
 
   /**
-   * Flags to be used upon output
-   * of gmv data in one space
-   * dimension. Can be changed by
-   * using the <tt>set_flags</tt>
+   * 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;
 
   /**
-   * Flags to be used upon output
-   * of Tecplot data in one space
-   * dimension. Can be changed by
-   * using the <tt>set_flags</tt>
+   * 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;
 
   /**
-   * Flags to be used upon output
-   * of vtk data in one space
-   * dimension. Can be changed by
-   * using the <tt>set_flags</tt>
+   * 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;
 
   /**
-   * Flags to be used upon output
-   * of svg data in one space
-   * dimension. Can be changed by
-   * using the <tt>set_flags</tt>
+   * 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;
 
   /**
-   * 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.
+   * 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;
 };
@@ -3118,60 +2657,36 @@ class DataOutReader : public DataOutInterface<dim,spacedim>
 {
 public:
   /**
-   * Read a sequence of patches as
-   * written previously by
-   * <tt>DataOutBase::write_deal_II_intermediate</tt>
-   * and store them in the present
-   * object. This overwrites any
-   * previous content.
+   * Read a sequence of patches as written previously by
+   * <tt>DataOutBase::write_deal_II_intermediate</tt> and store them
+   * in the present object. This overwrites any previous content.
    */
   void read (std::istream &in);
 
   /**
-   * This function can be used to
-   * merge the patches read by the
-   * other object into the patches
-   * that this present object
-   * stores. This is sometimes
-   * handy if one has, for example,
-   * a domain decomposition
-   * algorithm where each block is
-   * represented by a DoFHandler of
-   * its own, but one wants to
-   * output the solution on all the
-   * blocks at the same
-   * time. Alternatively, it may
-   * also be used for parallel
-   * programs, where each process
-   * only generates output for its
-   * share of the cells, even if
-   * all processes can see all
-   * cells.
-   *
-   * For this to work, the input
-   * files for the present object
-   * and the given argument need to
-   * have the same number of output
-   * vectors, and they need to use
-   * the same number of
-   * subdivisions per patch. The
-   * output will probably look
-   * rather funny if patches in
+   * This function can be used to merge the patches read by the other
+   * object into the patches that this present object stores. This is
+   * sometimes handy if one has, for example, a domain decomposition
+   * algorithm where each block is represented by a DoFHandler of its
+   * own, but one wants to output the solution on all the blocks at
+   * the same time. Alternatively, it may also be used for parallel
+   * programs, where each process only generates output for its share
+   * of the cells, even if all processes can see all cells.
+   *
+   * For this to work, the input files for the present object and the
+   * given argument need to have the same number of output vectors,
+   * and they need to use the same number of subdivisions per
+   * patch. The output will probably look rather funny if patches in
    * both objects overlap in space.
    *
-   * If you call read() for this
-   * object after merging in
-   * patches, the previous state is
-   * overwritten, and the merged-in
-   * patches are lost.
+   * If you call read() for this object after merging in patches, the
+   * previous state is overwritten, and the merged-in patches are
+   * lost.
    *
-   * This function will fail if
-   * either this or the other
-   * object did not yet set up any
-   * patches.
+   * This function will fail if either this or the other object did
+   * not yet set up any patches.
    *
-   * The use of this function is
-   * demonstrated in step-19.
+   * The use of this function is demonstrated in step-19.
    */
   void merge (const DataOutReader<dim,spacedim> &other);
 
@@ -3199,67 +2714,42 @@ public:
 
 protected:
   /**
-   * This is the function
-   * through which this class
-   * propagates preprocessed data in
-   * the form of Patch
-   * structures (declared in the
-   * base class DataOutBase) to
-   * the actual output
-   * function.
+   * This is the function through which this class propagates
+   * preprocessed data in the form of Patch structures (declared in
+   * the base class DataOutBase) to the actual output function.
    *
-   * It returns the patches as read
-   * the last time a stream was
-   * given to the read() function.
+   * 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> > &
   get_patches () const;
 
   /**
-   * Abstract virtual function
-   * through which the names of
-   * data sets are obtained by the
-   * output functions of the base
-   * class.
+   * Abstract virtual function through which the names of data sets
+   * are obtained by the output functions of the base class.
    *
-   * Return the names of the
-   * variables as read the last
-   * time we read a file.
+   * Return the names of the variables as read the last time we read a
+   * file.
    */
   virtual std::vector<std::string> get_dataset_names () const;
 
   /**
-   * This functions returns
-   * information about how the
-   * individual components of
-   * output files that consist of
-   * more than one data set are to
-   * be interpreted.
-   *
-   * It returns a list of index
-   * pairs and corresponding name
-   * indicating which components of
-   * the output are to be
-   * considered vector-valued
-   * rather than just a collection
-   * of scalar data. The index
-   * pairs are inclusive; for
-   * example, if we have a Stokes
-   * problem in 2d with components
-   * (u,v,p), then the
-   * corresponding vector data
-   * range should be (0,1), and the
-   * returned list would consist of
-   * only a single element with a
-   * tuple such as (0,1,"velocity").
-   *
-   * Since some of the derived
-   * classes do not know about
-   * vector data, this function has
-   * a default implementation that
-   * simply returns an empty
-   * string, meaning that all data
-   * is to be considered a
+   * This functions returns information about how the individual
+   * components of output files that consist of more than one data set
+   * are to be interpreted.
+   *
+   * It returns a list of index pairs and corresponding name
+   * indicating which components of the output are to be considered
+   * vector-valued rather than just a collection of scalar data. The
+   * index pairs are inclusive; for example, if we have a Stokes
+   * problem in 2d with components (u,v,p), then the corresponding
+   * vector data range should be (0,1), and the returned list would
+   * consist of only a single element with a tuple such as
+   * (0,1,"velocity").
+   *
+   * Since some of the derived classes do not know about vector data,
+   * this function has a default implementation that simply returns an
+   * empty string, meaning that all data is to be considered a
    * collection of scalar fields.
    */
   virtual
@@ -3268,20 +2758,15 @@ protected:
 
 private:
   /**
-   * Arrays holding the set of
-   * patches as well as the names
-   * of output variables, all of
-   * which we read from an input
-   * stream.
+   * 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<std::string> dataset_names;
 
   /**
-   * Information about whether
-   * certain components of the
-   * output field are to be
-   * considered vectors.
+   * Information about whether certain components of the output field
+   * are to be considered vectors.
    */
   std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
   vector_data_ranges;
index f6bfc184de8ec1befeb10d0a42438fd1f6612ebf..70712ea75177d5ae6fed929367ff753eafe8aadc 100644 (file)
@@ -369,7 +369,8 @@ namespace Patterns
 
 
   /**
-   * This pattern matches a list of comma-separated values each of which
+   * This pattern matches a list of values separated by commas (or another
+   * string), each of which
    * have to match a pattern given to the constructor. With two additional
    * parameters, the number of elements this list has to have can be
    * specified. If none is specified, the list may have zero or more
@@ -389,12 +390,14 @@ namespace Patterns
      * Constructor. Take the given parameter as the specification of valid
      * elements of the list.
      *
-     * The two other arguments can be used to denote minimal and maximal
-     * allowable lengths of the list.
+     * The three other arguments can be used to denote minimal and maximal
+     * allowable lengths of the list, and the string that is used as a
+     * separator between elements of the list.
      */
     List (const PatternBase  &base_pattern,
           const unsigned int  min_elements = 0,
-          const unsigned int  max_elements = max_int_value);
+          const unsigned int  max_elements = max_int_value,
+          const std::string  &separator = ",");
 
     /**
      * Destructor.
@@ -461,6 +464,11 @@ namespace Patterns
      */
     const unsigned int max_elements;
 
+    /**
+     * Separator between elements of the list.
+     */
+    const std::string separator;
+
     /**
      * Initial part of description
      */
@@ -474,7 +482,8 @@ namespace Patterns
    * pattern given to the constructor. For each entry of the map,
    * parameters have to be entered in the form <code>key: value</code>. In
    * other words, a map is described in the form
-   * <code>key1: value1, key2: value2, key3: value3, ...</code>.
+   * <code>key1: value1, key2: value2, key3: value3, ...</code>. A constructor
+   * argument allows to choose a delimiter between pairs other than the comma.
    *
    * With two additional parameters, the number of elements this list has
    * to have can be specified. If none is specified, the map may have zero
@@ -494,13 +503,15 @@ namespace Patterns
      * Constructor. Take the given parameter as the specification of valid
      * elements of the list.
      *
-     * The two other arguments can be used to denote minimal and maximal
-     * allowable lengths of the list.
+     * The three other arguments can be used to denote minimal and maximal
+     * allowable lengths of the list as well as the separator used to delimit
+     * pairs of the map.
      */
     Map (const PatternBase  &key_pattern,
          const PatternBase  &value_pattern,
          const unsigned int  min_elements = 0,
-         const unsigned int  max_elements = max_int_value);
+         const unsigned int  max_elements = max_int_value,
+         const std::string  &separator = ",");
 
     /**
      * Destructor.
@@ -568,6 +579,11 @@ namespace Patterns
      */
     const unsigned int max_elements;
 
+    /**
+     * Separator between elements of the list.
+     */
+    const std::string separator;
+
     /**
      * Initial part of description
      */
@@ -873,7 +889,7 @@ namespace Patterns
  *     set Geometry       = [0,1]x[0,3]
  *   @endcode
  *   Input may be sorted into subsection trees in order to give the input a
- *   logical structure.
+ *   logical structure, and input files may include other files.
  *
  *   The ParameterHandler class is discussed in detail in the @ref step_19
  *   "step-19" example program, and is used in more realistic situations in
@@ -1018,9 +1034,23 @@ namespace Patterns
  *   <tt>=</tt> sign.
  *
  *
+ *   <h3>Including other input files</h3>
+ *
+ *   An input file can include other include files using the syntax
+ *   @code
+ *     ...
+ *     include some_other_file.prm
+ *     ...
+ *   @endcode
+ *   The file so referenced is searched for relative to the current
+ *   directory (not relative to the directory in which the including
+ *   parameter file is located, since this is not known to all three
+ *   versions of the read_input() function).
+ *
+ *
  *   <h3>Reading data from input sources</h3>
  *
- *   In order to read input you can use three possibilities: reading from
+ *   In order to read input there are three possibilities: reading from
  *   an <tt>std::istream</tt> object, reading from a file of which the name
  *   is given and reading from a string in memory in which the lines are
  *   separated by <tt>@\n</tt> characters. These possibilities are used as
@@ -1559,12 +1589,15 @@ public:
   virtual ~ParameterHandler ();
 
   /**
-   * Read input from a stream until stream returns <tt>eof</tt> condition
-   * or error.
+   * Read input from a stream until the stream returns the <tt>eof</tt> condition
+   * or error. The second argument can be used to denote the name of the file
+   * (if that's what the input stream represents) we are reading from; this
+   * is only used when creating output for error messages.
    *
    * Return whether the read was successful.
    */
-  virtual bool read_input (std::istream &input);
+  virtual bool read_input (std::istream &input,
+                           const std::string &filename = "input file");
 
   /**
    * Read input from a file the name of which is given. The PathSearch
@@ -1615,8 +1648,14 @@ public:
    * this class is asked to write out all declarations to a stream using
    * the print_parameters() function.
    *
-   * The function generates an exception if the default value doesn't match
-   * the given pattern. An entry can be declared more than once without
+   * The function generates an exception of type ExcValueDoesNotMatchPattern
+   * if the default value doesn't match the given pattern, using the C++
+   * throw mechanism. However, this exception is only generated <i>after</i>
+   * the entry has been created; if you have code where no sensible default
+   * value for a parameter is possible, you can then catch and ignore this
+   * exception.
+   *
+   * @note An entry can be declared more than once without
    * generating an error, for example to override an earlier default value.
    */
   void declare_entry (const std::string           &entry,
@@ -1923,7 +1962,8 @@ private:
   std::string get_current_full_path (const std::string &name) const;
 
   /**
-   * Scan one line of input. <tt>lineno</tt> is the number of the line
+   * Scan one line of input. <tt>input_filename</tt> and <tt>lineno</tt>
+   * are the name of the input file and the current number of the line
    * presently scanned (for the logs if there are messages). Return
    * <tt>false</tt> if line contained stuff that could not be understood,
    * the uppermost subsection was to be left by an <tt>END</tt> or
@@ -1935,6 +1975,7 @@ private:
    * caller's variable is not changed.
    */
   bool scan_line (std::string         line,
+                  const std::string  &input_filename,
                   const unsigned int  lineno);
 
   friend class MultipleParameterLoop;
index 8006dba0d046b583338f78646f66c8a8bd3fa802..989591f843a11f8edac6caf2b03c71df820c4b9e 100644 (file)
@@ -3492,6 +3492,7 @@ namespace internal
 
 
 template <class DH, bool lda>
+inline
 TriaIterator<DoFAccessor<DH::dimension-1,DH,lda> >
 DoFCellAccessor<DH,lda>::face (const unsigned int i) const
 {
@@ -3519,6 +3520,7 @@ DoFCellAccessor<DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &
 }
 
 
+
 template<class DH, bool lda>
 inline
 void DoFCellAccessor<DH,lda>::get_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
@@ -3526,6 +3528,8 @@ void DoFCellAccessor<DH,lda>::get_mg_dof_indices (std::vector<types::global_dof_
   DoFAccessor<dim, DH,lda>::get_mg_dof_indices (this->level (), dof_indices);
 }
 
+
+
 template<class DH, bool lda>
 inline
 void DoFCellAccessor<DH,lda>::set_mg_dof_indices (const std::vector<types::global_dof_index> &dof_indices)
@@ -3534,6 +3538,7 @@ void DoFCellAccessor<DH,lda>::set_mg_dof_indices (const std::vector<types::globa
 }
 
 
+
 template<class DH, bool lda>
 inline
 void DoFCellAccessor<DH,lda>::get_active_or_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
@@ -3548,6 +3553,7 @@ void DoFCellAccessor<DH,lda>::get_active_or_mg_dof_indices (std::vector<types::g
 
 template <class DH, bool lda>
 template <class InputVector, typename number>
+inline
 void
 DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
                                          Vector<number>    &local_values) const
@@ -3564,6 +3570,7 @@ DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
 
 template <class DH, bool lda>
 template <class InputVector, typename ForwardIterator>
+inline
 void
 DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
                                          ForwardIterator    local_values_begin,
@@ -3579,6 +3586,7 @@ DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
 
 template <class DH, bool lda>
 template <class InputVector, typename ForwardIterator>
+inline
 void
 DoFCellAccessor<DH,lda>::get_dof_values (const ConstraintMatrix &constraints,
                                          const InputVector      &values,
@@ -3596,6 +3604,7 @@ DoFCellAccessor<DH,lda>::get_dof_values (const ConstraintMatrix &constraints,
 
 template <class DH, bool lda>
 template <class OutputVector, typename number>
+inline
 void
 DoFCellAccessor<DH,lda>::set_dof_values (const Vector<number> &local_values,
                                          OutputVector         &values) const
index 0661aa2c63794beae4605e836bab3c17134c3879..bb60046fc4da7d48918eef1ac80e1e879459768e 100644 (file)
@@ -209,6 +209,11 @@ public:
   std::size_t
   memory_consumption () const;
 
+  /**
+   * Exception
+   */
+  DeclException0 (ExcNoComponentSelected);
+
 private:
   /**
    * The actual component mask.
index 0722155e82e676afb864ab8112e2cc806edbcdea..1cc390f75142c0178417a6c7e8ff11ce6d9d13e1 100644 (file)
@@ -160,7 +160,12 @@ namespace FETools
    * indices of each local block. If it is false, then the block sizes are
    * returned.
    *
-   * @todo Which way does this vector map the numbers?
+   * The vector <tt>renumbering</tt> will be indexed by the standard
+   * numbering of local degrees of freedom, namely first first vertex,
+   * then second vertex, after vertices lines, quads, and hexes. For
+   * each index, the entry indicates the index which this degree of
+   * freedom receives in a numbering scheme, where the first block is
+   * numbered completely before the second.
    */
   template<int dim, int spacedim>
   void compute_block_renumbering (
index 85f900bf28023d8804255ec866eca9c5031cf9e2..62bbafecdaf5b49f89e7b5b5ffb5b2daba663ed4 100644 (file)
@@ -37,7 +37,7 @@ DEAL_II_NAMESPACE_OPEN
  *
  * To use this class, make sure that the
  * Boundary::@p get_normals_at_vertices function is implemented
- * for the users boundary object.
+ * for the user's boundary object.
  *
  * For more information about the <tt>spacedim</tt> template parameter
  * check the documentation of FiniteElement or the one of
@@ -50,71 +50,46 @@ class MappingC1 : public MappingQ<dim,spacedim>
 {
 public:
   /**
-   * Constructor. Pass the fixed
-   * degree @p 3 down to the base
-   * class, as a cubic mapping
-   * suffices to generate a
-   * continuous mapping of the
-   * boundary.
+   * Constructor. Pass the fixed degree @p 3 down to the base class, as a
+   * cubic mapping suffices to generate a continuous mapping of the boundary.
    */
   MappingC1 ();
 
   /**
-   * Return a pointer to a copy of the
-   * present object. The caller of this
-   * copy then assumes ownership of it.
+   * Return a pointer to a copy of the present object. The caller of this copy
+   * then assumes ownership of it.
    */
   virtual
   Mapping<dim,spacedim> *clone () const;
 
 protected:
   /**
-   * For <tt>dim=2,3</tt>. Append the
-   * support points of all shape
-   * functions located on bounding
-   * lines to the vector
-   * @p a. Points located on the
-   * line but on vertices are not
-   * included.
+   * For <tt>dim=2,3</tt>. Append the support points of all shape functions
+   * located on bounding lines to the vector @p a. Points located on the line
+   * but on vertices are not included.
    *
-   * Needed by the
-   * <tt>compute_support_points_simple(laplace)</tt>
-   * functions. For <tt>dim=1</tt> this
-   * function is empty.
+   * Needed by the <tt>compute_support_points_simple(laplace)</tt>
+   * functions. For <tt>dim=1</tt> this function is empty.
    *
-   * This function chooses the
-   * respective points not such
-   * that they are interpolating
-   * the boundary (as does the base
-   * class), but rather such that
-   * the resulting cubic mapping is
-   * a continuous one.
+   * This function chooses the respective points not such that they are
+   * interpolating the boundary (as does the base class), but rather such that
+   * the resulting cubic mapping is a continuous one.
    */
   virtual void
   add_line_support_points (const typename Triangulation<dim>::cell_iterator &cell,
                            std::vector<Point<dim> > &a) const;
 
   /**
-   * For <tt>dim=3</tt>. Append the
-   * support points of all shape
-   * functions located on bounding
-   * faces (quads in 3d) to the
-   * vector @p a. Points located
-   * on the line but on vertices
-   * are not included.
+   * For <tt>dim=3</tt>. Append the support points of all shape functions
+   * located on bounding faces (quads in 3d) to the vector @p a. Points
+   * located on the line but on vertices are not included.
    *
-   * Needed by the
-   * @p compute_support_points_laplace
-   * function. For <tt>dim=1</tt> and 2
-   * this function is empty.
+   * Needed by the @p compute_support_points_laplace function. For
+   * <tt>dim=1</tt> and 2 this function is empty.
    *
-   * This function chooses the
-   * respective points not such
-   * that they are interpolating
-   * the boundary (as does the base
-   * class), but rather such that
-   * the resulting cubic mapping is
-   * a continuous one.
+   * This function chooses the respective points not such that they are
+   * interpolating the boundary (as does the base class), but rather such that
+   * the resulting cubic mapping is a continuous one.
    */
   virtual void
   add_quad_support_points(const typename Triangulation<dim>::cell_iterator &cell,
index 484963727b0c16cd8ee65da5836b5d8e7237d942..28e4aefcbf1e75d334bc88c11bcfc2198c4b87d2 100644 (file)
@@ -32,9 +32,11 @@ template <int dim, typename POLY> class TensorProductPolynomials;
 /*@{*/
 
 /**
- * Mapping class that uses Qp-mappings on boundary cells. The mapping
- * shape functions make use of tensor product polynomials with
- * equidistant (on the unit cell) support points.
+ * Mapping class that uses Qp-mappings on boundary cells. The mapping shape
+ * functions make use of tensor product polynomials with unit cell support
+ * points equal to the points of the Gauss-Lobatto quadrature formula. These
+ * points give a well-conditioned interpolation also for very high orders and
+ * are therefore preferred over equidistant support points.
  *
  * For more details about Qp-mappings, see the `mapping' report at
  * <tt>deal.II/doc/reports/mapping_q/index.html</tt> in the `Reports'
@@ -44,6 +46,10 @@ template <int dim, typename POLY> class TensorProductPolynomials;
  * check the documentation of FiniteElement or the one of
  * Triangulation.
  *
+ * @note Since the boundary description is closely tied to the unit cell
+ * support points, new boundary descriptions need to explicitly use the
+ * Gauss-Lobatto points.
+ *
  * @author Ralf Hartmann, 2000, 2001, 2005; Guido Kanschat 2000, 2001
  */
 template <int dim, int spacedim=dim>
@@ -51,41 +57,25 @@ class MappingQ : public MappingQ1<dim,spacedim>
 {
 public:
   /**
-   * Constructor.  @p p gives the
-   * degree of mapping polynomials
-   * on boundary cells.
+   * Constructor.  @p p gives the degree of mapping polynomials on boundary
+   * cells.
    *
-   * The second argument determines
-   * whether the higher order
-   * mapping should also be used on
-   * interior cells. If its value
-   * is <code>false</code> (the
-   * default), the a lower-order
-   * mapping is used in the
-   * interior. This is sufficient
-   * for most cases where higher
-   * order mappings are only used
-   * to better approximate the
-   * boundary. In that case, cells
-   * bounded by straight lines are
-   * acceptable in the
-   * interior. However, there are
-   * cases where one would also
-   * like to use a higher order
-   * mapping in the interior. The
-   * MappingQEulerian class is one
-   * such case.
+   * The second argument determines whether the higher order mapping should
+   * also be used on interior cells. If its value is <code>false</code> (the
+   * default), the a lower-order mapping is used in the interior. This is
+   * sufficient for most cases where higher order mappings are only used to
+   * better approximate the boundary. In that case, cells bounded by straight
+   * lines are acceptable in the interior. However, there are cases where one
+   * would also like to use a higher order mapping in the interior. The
+   * MappingQEulerian class is one such case.
    */
   MappingQ (const unsigned int p,
             const bool use_mapping_q_on_all_cells = false);
 
   /**
-   * Copy constructor. Performs a
-   * deep copy, i.e. duplicates
-   * what #tensor_pols points to
-   * instead of simply copying the
-   * #tensor_pols pointer as done
-   * by a default copy constructor.
+   * Copy constructor. Performs a deep copy, i.e. duplicates what #tensor_pols
+   * points to instead of simply copying the #tensor_pols pointer as done by a
+   * default copy constructor.
    */
   MappingQ (const MappingQ<dim,spacedim> &mapping);
 
@@ -95,10 +85,8 @@ public:
   virtual ~MappingQ ();
 
   /**
-   * Transforms the point @p p on
-   * the unit cell to the point
-   * @p p_real on the real cell
-   * @p cell and returns @p p_real.
+   * Transforms the point @p p on the unit cell to the point @p p_real on the
+   * real cell @p cell and returns @p p_real.
    */
   virtual Point<spacedim>
   transform_unit_to_real_cell (
@@ -106,46 +94,25 @@ public:
     const Point<dim>                                 &p) const;
 
   /**
-   * Transforms the point @p p on
-   * the real cell to the point
-   * @p p_unit on the unit cell
-   * @p cell and returns @p p_unit.
+   * Transforms the point @p p on the real cell to the point @p p_unit on the
+   * unit cell @p cell and returns @p p_unit.
    *
-   * Uses Newton iteration and the
-   * @p transform_unit_to_real_cell
-   * function.
+   * Uses Newton iteration and the @p transform_unit_to_real_cell function.
    *
-   * In the codimension one case,
-   * this function returns the
-   * normal projection of the real
-   * point @p p on the curve or
-   * surface identified by the @p
-   * cell.
+   * In the codimension one case, this function returns the normal projection
+   * of the real point @p p on the curve or surface identified by the @p cell.
    *
-   * @note Polynomial mappings from
-   * the reference (unit) cell coordinates
-   * to the coordinate system of a real
-   * cell are not always invertible if
-   * the point for which the inverse
-   * mapping is to be computed lies
-   * outside the cell's boundaries.
-   * In such cases, the current function
-   * may fail to compute a point on
-   * the reference cell whose image
-   * under the mapping equals the given
-   * point @p p.  If this is the case
-   * then this function throws an
-   * exception of type
-   * Mapping::ExcTransformationFailed .
-   * Whether the given point @p p lies
-   * outside the cell can therefore be
-   * determined by checking whether the
-   * return reference coordinates lie
-   * inside of outside the reference
-   * cell (e.g., using
-   * GeometryInfo::is_inside_unit_cell)
-   * or whether the exception mentioned
-   * above has been thrown.
+   * @note Polynomial mappings from the reference (unit) cell coordinates to
+   * the coordinate system of a real cell are not always invertible if the
+   * point for which the inverse mapping is to be computed lies outside the
+   * cell's boundaries.  In such cases, the current function may fail to
+   * compute a point on the reference cell whose image under the mapping
+   * equals the given point @p p.  If this is the case then this function
+   * throws an exception of type Mapping::ExcTransformationFailed .  Whether
+   * the given point @p p lies outside the cell can therefore be determined by
+   * checking whether the return reference coordinates lie inside of outside
+   * the reference cell (e.g., using GeometryInfo::is_inside_unit_cell) or
+   * whether the exception mentioned above has been thrown.
    */
   virtual Point<dim>
   transform_real_to_unit_cell (
@@ -172,23 +139,20 @@ public:
              const MappingType type) const;
 
   /**
-   * Return the degree of the
-   * mapping, i.e. the value which
-   * was passed to the constructor.
+   * Return the degree of the mapping, i.e. the value which was passed to the
+   * constructor.
    */
   unsigned int get_degree () const;
 
   /**
-   * Return a pointer to a copy of the
-   * present object. The caller of this
-   * copy then assumes ownership of it.
+   * Return a pointer to a copy of the present object. The caller of this copy
+   * then assumes ownership of it.
    */
   virtual
   Mapping<dim,spacedim> *clone () const;
 
   /**
-   * Storage for internal data of
-   * Q_degree transformation.
+   * Storage for internal data of Q_degree transformation.
    */
   class InternalData : public MappingQ1<dim,spacedim>::InternalData
   {
@@ -200,50 +164,35 @@ public:
 
 
     /**
-     * Return an estimate (in
-     * bytes) or the memory
-     * consumption of this
-     * object.
+     * Return an estimate (in bytes) or the memory consumption of this object.
      */
     virtual std::size_t memory_consumption () const;
 
     /**
-     * Unit normal vectors. Used
-     * for the alternative
-     * computation of the normal
-     * vectors. See doc of the
-     * @p alternative_normals_computation
-     * flag.
+     * Unit normal vectors. Used for the alternative computation of the normal
+     * vectors. See doc of the @p alternative_normals_computation flag.
      *
-     * Filled (hardcoded) once in
-     * @p get_face_data.
+     * Filled (hardcoded) once in @p get_face_data.
      */
     std::vector<std::vector<Point<dim> > > unit_normals;
 
     /**
-     * Flag that is set by the
-     * <tt>fill_fe_[[sub]face]_values</tt>
-     * function.
+     * Flag that is set by the <tt>fill_fe_[[sub]face]_values</tt> function.
      *
-     * If this flag is @p true
-     * we are on an interior cell
-     * and the
-     * @p mapping_q1_data is
-     * used.
+     * If this flag is @p true we are on an interior cell and the @p
+     * mapping_q1_data is used.
      */
     bool use_mapping_q1_on_current_cell;
 
     /**
-     * On interior cells
-     * @p MappingQ1 is used.
+     * On interior cells @p MappingQ1 is used.
      */
     typename MappingQ1<dim,spacedim>::InternalData mapping_q1_data;
   };
 
 protected:
   /**
-   * Implementation of the interface in
-   * Mapping.
+   * Implementation of the interface in Mapping.
    */
   virtual void
   fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
@@ -258,8 +207,7 @@ protected:
                   CellSimilarity::Similarity                           &cell_similarity) const ;
 
   /**
-   * Implementation of the interface in
-   * Mapping.
+   * Implementation of the interface in Mapping.
    */
   virtual void
   fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
@@ -272,8 +220,7 @@ protected:
                        typename std::vector<Point<spacedim> >        &normal_vectors) const ;
 
   /**
-   * Implementation of the interface in
-   * Mapping.
+   * Implementation of the interface in Mapping.
    */
   virtual void
   fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
@@ -287,55 +234,32 @@ protected:
                           typename std::vector<Point<spacedim> >        &normal_vectors) const ;
 
   /**
-   * For <tt>dim=2,3</tt>. Append the
-   * support points of all shape
-   * functions located on bounding
-   * lines to the vector
-   * @p a. Points located on the
-   * line but not on vertices are not
-   * included.
+   * For <tt>dim=2,3</tt>. Append the support points of all shape functions
+   * located on bounding lines to the vector @p a. Points located on the line
+   * but not on vertices are not included.
    *
-   * Needed by the
-   * @p compute_support_points_laplace
-   * function . For <tt>dim=1</tt> this
-   * function is empty.
+   * Needed by the @p compute_support_points_laplace function . For
+   * <tt>dim=1</tt> this function is empty.
    *
-   * This function is made virtual
-   * in order to allow derived
-   * classes to choose shape
-   * function support points
-   * differently than the present
-   * class, which chooses the
-   * points as interpolation points
-   * on the boundary.
+   * This function is made virtual in order to allow derived classes to choose
+   * shape function support points differently than the present class, which
+   * chooses the points as interpolation points on the boundary.
    */
   virtual void
   add_line_support_points (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                            std::vector<Point<spacedim> > &a) const;
 
   /**
-   * For <tt>dim=3</tt>. Append the
-   * support points of all shape
-   * functions located on bounding
-   * faces (quads in 3d) to the
-   * vector @p a. Points located
-   * on the quad but not on vertices
-   * are not included.
+   * For <tt>dim=3</tt>. Append the support points of all shape functions
+   * located on bounding faces (quads in 3d) to the vector @p a. Points
+   * located on the quad but not on vertices are not included.
    *
-   * Needed by the
-   * @p compute_support_points_laplace
-   * function. For <tt>dim=1</tt> and
-   * <tt>dim=2</tt> this function is
-   * empty.
+   * Needed by the @p compute_support_points_laplace function. For
+   * <tt>dim=1</tt> and <tt>dim=2</tt> this function is empty.
    *
-   * This function is made virtual
-   * in order to allow derived
-   * classes to choose shape
-   * function support points
-   * differently than the present
-   * class, which chooses the
-   * points as interpolation points
-   * on the boundary.
+   * This function is made virtual in order to allow derived classes to choose
+   * shape function support points differently than the present class, which
+   * chooses the points as interpolation points on the boundary.
    */
   virtual void
   add_quad_support_points(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
@@ -359,145 +283,99 @@ private:
                     const Quadrature<dim-1>& quadrature) const;
 
   /**
-   * Compute shape values and/or
-   * derivatives.
+   * Compute shape values and/or derivatives.
    */
   virtual void
   compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
                           typename MappingQ1<dim,spacedim>::InternalData &data) const;
 
   /**
-   * This function is needed by the
-   * constructor of <tt>MappingQ<dim,spacedim></tt>
-   * for <tt>dim=</tt> 2 and 3.
+   * This function is needed by the constructor of
+   * <tt>MappingQ<dim,spacedim></tt> for <tt>dim=</tt> 2 and 3.
    *
-   * For <tt>degree<4</tt> this function
-   * sets the
-   * @p laplace_on_quad_vector to
-   * the hardcoded data. For
-   * <tt>degree>=4</tt> and MappingQ<2>
-   * this vector is computed.
+   * For <tt>degree<4</tt> this function sets the @p laplace_on_quad_vector to
+   * the hardcoded data. For <tt>degree>=4</tt> and MappingQ<2> this vector is
+   * computed.
    *
-   * For the definition of the
-   * @p laplace_on_quad_vector
-   * please refer to equation (8)
-   * of the `mapping' report.
+   * For the definition of the @p laplace_on_quad_vector please refer to
+   * equation (8) of the `mapping' report.
    */
   void
   set_laplace_on_quad_vector(Table<2,double> &loqvs) const;
 
   /**
-   * This function is needed by the
-   * constructor of <tt>MappingQ<3></tt>.
+   * This function is needed by the constructor of <tt>MappingQ<3></tt>.
    *
-   * For <tt>degree==2</tt> this function
-   * sets the
-   * @p laplace_on_hex_vector to
-   * the hardcoded data. For
-   * <tt>degree>2</tt> this vector is
-   * computed.
+   * For <tt>degree==2</tt> this function sets the @p laplace_on_hex_vector to
+   * the hardcoded data. For <tt>degree>2</tt> this vector is computed.
    *
-   * For the definition of the
-   * @p laplace_on_hex_vector
-   * please refer to equation (8)
-   * of the `mapping' report.
+   * For the definition of the @p laplace_on_hex_vector please refer to
+   * equation (8) of the `mapping' report.
    */
   void set_laplace_on_hex_vector(Table<2,double> &lohvs) const;
 
   /**
-   * Computes the
-   * <tt>laplace_on_quad(hex)_vector</tt>.
+   * Computes the <tt>laplace_on_quad(hex)_vector</tt>.
    *
-   * Called by the
-   * <tt>set_laplace_on_quad(hex)_vector</tt>
-   * functions if the data is not
-   * yet hardcoded.
+   * Called by the <tt>set_laplace_on_quad(hex)_vector</tt> functions if the
+   * data is not yet hardcoded.
    *
-   * For the definition of the
-   * <tt>laplace_on_quad(hex)_vector</tt>
-   * please refer to equation (8)
-   * of the `mapping' report.
+   * For the definition of the <tt>laplace_on_quad(hex)_vector</tt> please
+   * refer to equation (8) of the `mapping' report.
    */
   void compute_laplace_vector(Table<2,double> &lvs) const;
 
   /**
-   * Takes a
-   * <tt>laplace_on_hex(quad)_vector</tt>
-   * and applies it to the vector
-   * @p a to compute the inner
-   * support points as a linear
-   * combination of the exterior
-   * points.
+   * Takes a <tt>laplace_on_hex(quad)_vector</tt> and applies it to the vector
+   * @p a to compute the inner support points as a linear combination of the
+   * exterior points.
    *
-   * The vector @p a initially
-   * contains the locations of the
-   * @p n_outer points, the
-   * @p n_inner computed inner
-   * points are appended.
+   * The vector @p a initially contains the locations of the @p n_outer
+   * points, the @p n_inner computed inner points are appended.
    *
-   * See equation (7) of the
-   * `mapping' report.
+   * See equation (7) of the `mapping' report.
    */
   void apply_laplace_vector(const Table<2,double>   &lvs,
                             std::vector<Point<spacedim> > &a) const;
 
   /**
-   * Computes the support points of
-   * the mapping.
+   * Computes the support points of the mapping.
    */
   virtual void compute_mapping_support_points(
     const typename Triangulation<dim,spacedim>::cell_iterator &cell,
     std::vector<Point<spacedim> > &a) const;
 
   /**
-   * Computes all support points of
-   * the mapping shape
-   * functions. The inner support
-   * points (ie. support points in
-   * quads for 2d, in hexes for 3d)
-   * are computed using the
-   * solution of a Laplace equation
-   * with the position of the outer
-   * support points as boundary
-   * values, in order to make the
-   * transformation as smooth as
-   * possible.
+   * Computes all support points of the mapping shape functions. The inner
+   * support points (ie. support points in quads for 2d, in hexes for 3d) are
+   * computed using the solution of a Laplace equation with the position of
+   * the outer support points as boundary values, in order to make the
+   * transformation as smooth as possible.
    */
   void compute_support_points_laplace(
     const typename Triangulation<dim,spacedim>::cell_iterator &cell,
     std::vector<Point<spacedim> > &a) const;
 
   /**
-   * Needed by the
-   * @p laplace_on_quad function
-   * (for <tt>dim==2</tt>). Filled by the
-   * constructor.
+   * Needed by the @p laplace_on_quad function (for <tt>dim==2</tt>). Filled
+   * by the constructor.
    *
    * Sizes:
-   * laplace_on_quad_vector.size()=
-   *   number of inner
-   *   unit_support_points
-   * laplace_on_quad_vector[i].size()=
-   *   number of outer
-   *   unit_support_points, i.e.
-   *   unit_support_points on the
-   *   boundary of the quad
+   * laplace_on_quad_vector.size()= number of inner unit_support_points
+   * laplace_on_quad_vector[i].size()= number of outer unit_support_points,
+   *   i.e.  unit_support_points on the boundary of the quad
    *
-   * For the definition of this
-   * vector see equation (8) of the
-   * `mapping' report.
+   * For the definition of this vector see equation (8) of the `mapping'
+   * report.
    */
   Table<2,double> laplace_on_quad_vector;
 
   /**
-   * Needed by the
-   * @p laplace_on_hex function
-   * (for <tt>dim==3</tt>). Filled by the
-   * constructor.
+   * Needed by the @p laplace_on_hex function (for <tt>dim==3</tt>). Filled by
+   * the constructor.
    *
-   * For the definition of this
-   * vector see equation (8) of the
-   * `mapping' report.
+   * For the definition of this vector see equation (8) of the `mapping'
+   * report.
    */
   Table<2,double> laplace_on_hex_vector;
 
@@ -509,69 +387,57 @@ private:
                   << "laplace_vector not set for degree=" << arg1 << ".");
 
   /**
-   * Degree @p p of the
-   * polynomials used as shape
-   * functions for the Qp mapping
+   * Degree @p p of the polynomials used as shape functions for the Qp mapping
    * of cells at the boundary.
    */
   const unsigned int degree;
 
   /**
-   * Number of inner mapping shape
-   * functions.
+   * Number of inner mapping shape functions.
    */
   const unsigned int n_inner;
 
   /**
-   * Number of mapping shape
-   * functions on the boundary.
+   * Number of mapping shape functions on the boundary.
    */
   const unsigned int n_outer;
 
   /**
-   * Pointer to the
-   * @p dim-dimensional tensor
-   * product polynomials used as
-   * shape functions for the Qp
-   * mapping of cells at the
-   * boundary.
+   * Pointer to the @p dim-dimensional tensor product polynomials used as
+   * shape functions for the Qp mapping of cells at the boundary.
    */
   const TensorProductPolynomials<dim> *tensor_pols;
 
   /**
-   * Number of the Qp tensor
-   * product shape functions.
+   * Number of the Qp tensor product shape functions.
    */
   const unsigned int n_shape_functions;
 
   /**
-   * Mapping from lexicographic to
-   * to the Qp shape function
-   * numbering. Its size is
-   * @p dofs_per_cell.
+   * Mapping from lexicographic to to the Qp shape function numbering. Its
+   * size is @p dofs_per_cell.
    */
   const std::vector<unsigned int> renumber;
 
   /**
-   * If this flag is set @p true
-   * then @p MappingQ is used on
-   * all cells, not only on
-   * boundary cells.
+   * If this flag is set @p true then @p MappingQ is used on all cells, not
+   * only on boundary cells.
    */
   const bool use_mapping_q_on_all_cells;
 
   /**
-   * An FE_Q object which is only needed in
-   * 3D, since it knows how to reorder shape
-   * functions/DoFs on non-standard
-   * faces. This is used to reorder support
-   * points in the same way. We could make
-   * this a pointer to prevent construction
-   * in 1D and 2D, but since memory and time
-   * requirements are not particularly high
-   * this seems unnecessary at the moment.
+   * An FE_Q object which is only needed in 3D, since it knows how to reorder
+   * shape functions/DoFs on non-standard faces. This is used to reorder
+   * support points in the same way. We could make this a pointer to prevent
+   * construction in 1D and 2D, but since memory and time requirements are not
+   * particularly high this seems unnecessary at the moment.
    */
   const FE_Q<dim> feq;
+
+  /**
+   * Declare other MappingQ classes friends.
+   */
+  template <int,int> friend class MappingQ;
 };
 
 /*@}*/
index 4d4ba9cc9cfdcc0ea58d0a83562922b964f56555..f0a79f1066f4c30b4026c06e082e0b6cdead19cf 100644 (file)
@@ -95,25 +95,14 @@ class MappingQEulerian : public MappingQ<dim, spacedim>
 {
 public:
   /**
-   * Constructor. The first argument is
-   * the polynomical degree of the desired
-   * Qp mapping.  It then takes a
-   * <tt>Vector<double> &</tt> to specify the
-   * transformation of the domain
-   * from the reference to
-   * the current configuration.
-   * The organization of the
-   * elements in the @p Vector
-   * must follow the concept how
-   * deal.II stores solutions that
-   * are associated to a
-   * triangulation.  This is
-   * automatically the case if the
-   * @p Vector represents the
-   * solution of the previous step
-   * of a nonlinear problem.
-   * Alternatively, the @p Vector
-   * can be initialized by
+   * Constructor. The first argument is the polynomical degree of the desired
+   * Qp mapping.  It then takes a <tt>Vector<double> &</tt> to specify the
+   * transformation of the domain from the reference to the current
+   * configuration.  The organization of the elements in the @p Vector must
+   * follow the concept how deal.II stores solutions that are associated to a
+   * triangulation.  This is automatically the case if the @p Vector
+   * represents the solution of the previous step of a nonlinear problem.
+   * Alternatively, the @p Vector can be initialized by
    * <tt>DoFAccessor::set_dof_values()</tt>.
    */
 
@@ -122,20 +111,16 @@ public:
                     const DoFHandler<dim,spacedim>  &euler_dof_handler);
 
   /**
-   * Return a pointer to a copy of the
-   * present object. The caller of this
-   * copy then assumes ownership of it.
+   * Return a pointer to a copy of the present object. The caller of this copy
+   * then assumes ownership of it.
    */
   virtual
   Mapping<dim,spacedim> *clone () const;
 
   /**
-   * Always returns @p false because
-   * MappingQ1Eulerian does not in general
-   * preserve vertex locations (unless the
-   * translation vector happens to provide
-   * for zero displacements at vertex
-   * locations).
+   * Always returns @p false because MappingQ1Eulerian does not in general
+   * preserve vertex locations (unless the translation vector happens to
+   * provide for zero displacements at vertex locations).
    */
   bool preserves_vertex_locations () const;
 
@@ -146,10 +131,8 @@ public:
 
 protected:
   /**
-   * Implementation of the interface in
-   * MappingQ. Overrides the function in
-   * the base class, since we cannot use
-   * any cell similarity for this class.
+   * Implementation of the interface in MappingQ. Overrides the function in
+   * the base class, since we cannot use any cell similarity for this class.
    */
   virtual void
   fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
@@ -164,36 +147,29 @@ protected:
                   CellSimilarity::Similarity                           &cell_similarity) const;
 
   /**
-   * Reference to the vector of
-   * shifts.
+   * Reference to the vector of shifts.
    */
 
   SmartPointer<const VECTOR, MappingQEulerian<dim,VECTOR,spacedim> > euler_vector;
 
   /**
-   * Pointer to the DoFHandler to
-   * which the mapping vector is
-   * associated.
+   * Pointer to the DoFHandler to which the mapping vector is associated.
    */
-
   SmartPointer<const DoFHandler<dim,spacedim>,MappingQEulerian<dim,VECTOR,spacedim> > euler_dof_handler;
 
 
 private:
 
   /**
-   * Special quadrature rule used
-   * to define the support points
-   * in the reference configuration.
+   * Special quadrature rule used to define the support points in the
+   * reference configuration.
    */
 
   class SupportQuadrature : public Quadrature<dim>
   {
   public:
     /**
-     * Constructor, with an argument
-     * defining the desired polynomial
-     * degree.
+     * Constructor, with an argument defining the desired polynomial degree.
      */
 
     SupportQuadrature (const unsigned int map_degree);
@@ -201,36 +177,26 @@ private:
   };
 
   /**
-   * A member variable holding the
-   * quadrature points in the right
-   * order.
+   * A member variable holding the quadrature points in the right order.
    */
   const SupportQuadrature support_quadrature;
 
   /**
-   * FEValues object used to query the
-   * the given finite element field
-   * at the support points in the
-   * reference configuration.
+   * FEValues object used to query the the given finite element field at the
+   * support points in the reference configuration.
    *
-   * The variable is marked as
-   * mutable since we have to call
-   * FEValues::reinit from
-   * compute_mapping_support_points,
-   * a function that is 'const'.
+   * The variable is marked as mutable since we have to call FEValues::reinit
+   * from compute_mapping_support_points, a function that is 'const'.
    */
   mutable FEValues<dim,spacedim> fe_values;
 
   /**
-   * A variable to guard access to
-   * the fe_values variable.
+   * A variable to guard access to the fe_values variable.
    */
   mutable Threads::Mutex fe_values_mutex;
 
   /**
-   * Compute the positions of the
-   * support points in the current
-   * configuration
+   * Compute the positions of the support points in the current configuration
    */
   virtual void compute_mapping_support_points(
     const typename Triangulation<dim,spacedim>::cell_iterator &cell,
index e74d18321ddd4800fe17c925a9797a5eef8d3355..994f59ef17b2d34a9590b34fb09f4cbec6658034 100644 (file)
@@ -1593,7 +1593,7 @@ public:
     virtual
     void
     create_notification (const Triangulation<dim, spacedim> &tria);
-  }; // DEAL_II_DEPRECATED;
+  }; 
 
   /**
    * A structure that is used as an
index ba830652009fd7ca89fa0cb4ff92d06d50448ad7..ca948550fc7d75638a145bea0bcb8ed527f39ab9 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <deal.II/base/config.h>
 #include <deal.II/base/subscriptor.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/thread_management.h>
 #include <deal.II/base/point.h>
 #include <deal.II/grid/tria.h>
 
@@ -85,120 +87,75 @@ class Boundary : public Subscriptor
 public:
 
   /**
-   * Type keeping information about
-   * the normals at the vertices of
-   * a face of a cell. Thus, there
-   * are
-   * <tt>GeometryInfo<dim>::vertices_per_face</tt>
-   * normal vectors, that define
-   * the tangent spaces of the
-   * boundary at the vertices. Note
-   * that the vectors stored in
-   * this object are not required
-   * to be normalized, nor to
-   * actually point outward, as one
-   * often will only want to check
-   * for orthogonality to define
-   * the tangent plane; if a
-   * function requires the normals
-   * to be normalized, then it must
-   * do so itself.
+   * Type keeping information about the normals at the vertices of a face of a
+   * cell. Thus, there are <tt>GeometryInfo<dim>::vertices_per_face</tt>
+   * normal vectors, that define the tangent spaces of the boundary at the
+   * vertices. Note that the vectors stored in this object are not required to
+   * be normalized, nor to actually point outward, as one often will only want
+   * to check for orthogonality to define the tangent plane; if a function
+   * requires the normals to be normalized, then it must do so itself.
    *
-   * For obvious reasons, this
-   * type is not useful in 1d.
+   * For obvious reasons, this type is not useful in 1d.
    */
   typedef Tensor<1,spacedim> FaceVertexNormals[GeometryInfo<dim>::vertices_per_face];
 
   /**
-   * Destructor. Does nothing here, but
-   * needs to be declared to make it
+   * Destructor. Does nothing here, but needs to be declared to make it
    * virtual.
    */
   virtual ~Boundary ();
 
   /**
-   * Return the point which shall
-   * become the new middle vertex
-   * of the two children of a
-   * regular line. In 2D, this line
-   * is a line at the boundary,
-   * while in 3d, it is bounding a
-   * face at the boundary (the
-   * lines therefore is also on the
-   * boundary).
+   * Return the point which shall become the new middle vertex of the two
+   * children of a regular line. In 2D, this line is a line at the boundary,
+   * while in 3d, it is bounding a face at the boundary (the lines therefore
+   * is also on the boundary).
    */
   virtual
   Point<spacedim>
   get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const = 0;
 
   /**
-   * Return the point which shall
-   * become the common point of the
-   * four children of a quad at the
-   * boundary in three or more
-   * spatial dimensions. This
-   * function therefore is only
-   * useful in at least three
-   * dimensions and should not be
-   * called for lower dimensions.
+   * Return the point which shall become the common point of the four children
+   * of a quad at the boundary in three or more spatial dimensions. This
+   * function therefore is only useful in at least three dimensions and should
+   * not be called for lower dimensions.
    *
-   * This function is called after
-   * the four lines bounding the
-   * given @p quad are refined, so
-   * you may want to use the
-   * information provided by
-   * <tt>quad->line(i)->child(j)</tt>,
-   * <tt>i=0...3</tt>, <tt>j=0,1</tt>.
+   * This function is called after the four lines bounding the given @p quad
+   * are refined, so you may want to use the information provided by
+   * <tt>quad->line(i)->child(j)</tt>, <tt>i=0...3</tt>, <tt>j=0,1</tt>.
    *
-   * Because in 2D, this function
-   * is not needed, it is not made
-   * pure virtual, to avoid the
-   * need to overload it.  The
-   * default implementation throws
-   * an error in any case, however.
+   * Because in 2D, this function is not needed, it is not made pure virtual,
+   * to avoid the need to overload it.  The default implementation throws an
+   * error in any case, however.
    */
   virtual
   Point<spacedim>
   get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
 
   /**
-   * Depending on <tt>dim=2</tt> or
-   * <tt>dim=3</tt> this function
-   * calls the
-   * get_new_point_on_line or the
-   * get_new_point_on_quad
-   * function. It throws an
-   * exception for
-   * <tt>dim=1</tt>. This wrapper
-   * allows dimension independent
+   * Depending on <tt>dim=2</tt> or <tt>dim=3</tt> this function calls the
+   * get_new_point_on_line or the get_new_point_on_quad function. It throws an
+   * exception for <tt>dim=1</tt>. This wrapper allows dimension independent
    * programming.
    */
   Point<spacedim>
   get_new_point_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face) const;
 
   /**
-   * Return equally spaced
-   * intermediate points on a line.
+   * Return intermediate points on a line spaced according to the interior
+   * support points of the 1D Gauss-Lobatto quadrature formula.
    *
-   * The number of points requested
-   * is given by the size of the
-   * vector @p points. It is the
-   * task of the derived classes to
-   * arrange the points in
+   * The number of points requested is given by the size of the vector @p
+   * points. It is the task of the derived classes to arrange the points in
    * approximately equal distances.
    *
-   * This function is called by the
-   * @p MappingQ class. This
-   * happens on each face line of a
-   * cells that has got at least
-   * one boundary line.
+   * This function is called by the @p MappingQ class. This happens on each
+   * face line of a cells that has got at least one boundary line.
    *
-   * As this function is not needed
-   * for @p MappingQ1, it is not
-   * made pure virtual, to avoid
-   * the need to overload it.  The
-   * default implementation throws
-   * an error in any case, however.
+   * As this function is not needed for @p MappingQ1, it is not made pure
+   * virtual, to avoid the need to overload it.  The default implementation
+   * throws an error in any case, however.
    */
   virtual
   void
@@ -206,34 +163,23 @@ public:
                                    std::vector<Point<spacedim> > &points) const;
 
   /**
-   * Return equally spaced
-   * intermediate points on a
-   * boundary quad.
+   * Return intermediate points on a line spaced according to the tensor
+   * product of the interior support points of the 1D Gauss-Lobatto quadrature
+   * formula.
    *
-   * The number of points requested
-   * is given by the size of the
-   * vector @p points. It is
-   * required that this number is a
-   * square of another integer,
-   * i.e. <tt>n=points.size()=m*m</tt>. It
-   * is the task of the derived
-   * classes to arrange the points
-   * such they split the quad into
-   * <tt>(m+1)(m+1)</tt> approximately
-   * equal-sized subquads.
+   * The number of points requested is given by the size of the vector @p
+   * points. It is required that this number is a square of another integer,
+   * i.e. <tt>n=points.size()=m*m</tt>. It is the task of the derived classes
+   * to arrange the points such they split the quad into <tt>(m+1)(m+1)</tt>
+   * approximately equal-sized subquads.
    *
-   * This function is called by the
-   * <tt>MappingQ<3></tt> class. This
-   * happens each face quad of
-   * cells in 3d that has got at
-   * least one boundary face quad.
+   * This function is called by the <tt>MappingQ<3></tt> class. This happens
+   * each face quad of cells in 3d that has got at least one boundary face
+   * quad.
    *
-   * As this function is not needed
-   * for @p MappingQ1, it is not
-   * made pure virtual, to avoid
-   * the need to overload it.  The
-   * default implementation throws
-   * an error in any case, however.
+   * As this function is not needed for @p MappingQ1, it is not made pure
+   * virtual, to avoid the need to overload it.  The default implementation
+   * throws an error in any case, however.
    */
   virtual
   void
@@ -241,56 +187,36 @@ public:
                                    std::vector<Point<spacedim> > &points) const;
 
   /**
-   * Depending on <tt>dim=2</tt> or
-   * <tt>dim=3</tt> this function
-   * calls the
-   * get_intermediate_points_on_line
-   * or the
-   * get_intermediate_points_on_quad
-   * function. It throws an
-   * exception for
-   * <tt>dim=1</tt>. This wrapper
-   * allows dimension independent
-   * programming.
+   * Depending on <tt>dim=2</tt> or <tt>dim=3</tt> this function calls the
+   * get_intermediate_points_on_line or the get_intermediate_points_on_quad
+   * function. It throws an exception for <tt>dim=1</tt>. This wrapper allows
+   * dimension independent programming.
    */
   void
   get_intermediate_points_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face,
                                    std::vector<Point<spacedim> > &points) const;
 
   /**
-   * Return the normal vector to the surface
-   * at the point p. If p is not in fact
-   * on the surface, but only closeby,
-   * try to return something reasonable,
-   * for example the normal vector
-   * at the surface point closest to p.
-   * (The point p will in fact not normally
-   * lie on the actual surface, but rather
-   * be a quadrature point mapped by some
-   * polynomial mapping; the mapped surface,
-   * however, will not usually coincide with
-   * the actual surface.)
+   * Return the normal vector to the surface at the point p. If p is not in
+   * fact on the surface, but only close-by, try to return something
+   * reasonable, for example the normal vector at the surface point closest to
+   * p.  (The point p will in fact not normally lie on the actual surface, but
+   * rather be a quadrature point mapped by some polynomial mapping; the
+   * mapped surface, however, will not usually coincide with the actual
+   * surface.)
    *
-   * The face iterator gives an indication
-   * which face this function is supposed
-   * to compute the normal vector for.
-   * This is useful if the boundary of
-   * the domain is composed of different
-   * nondifferential pieces (for example
-   * when using the StraightBoundary class
-   * to approximate a geometry that is
-   * completely described by the coarse mesh,
-   * with piecewise (bi-)linear components
-   * between the vertices, but where the
-   * boundary may have a kink at the vertices
-   * itself).
+   * The face iterator gives an indication which face this function is
+   * supposed to compute the normal vector for.  This is useful if the
+   * boundary of the domain is composed of different nondifferential pieces
+   * (for example when using the StraightBoundary class to approximate a
+   * geometry that is completely described by the coarse mesh, with piecewise
+   * (bi-)linear components between the vertices, but where the boundary may
+   * have a kink at the vertices itself).
    *
-   * @note Implementations of this function
-   * should be able to assume that the point p
-   * lies within or close to the face described by the
-   * first argument. In turn, callers of this
-   * function should ensure that this is
-   * in fact the case.
+   * @note Implementations of this function should be able to assume that the
+   * point p lies within or close to the face described by the first
+   * argument. In turn, callers of this function should ensure that this is in
+   * fact the case.
    */
   virtual
   Tensor<1,spacedim>
@@ -298,32 +224,17 @@ public:
                  const Point<spacedim> &p) const;
 
   /**
-   * Compute the normal vectors to
-   * the boundary at each vertex of
-   * the given face. It is not
-   * required that the normal
-   * vectors be normed
-   * somehow. Neither is it
-   * required that the normals
-   * actually point outward.
+   * Compute the normal vectors to the boundary at each vertex of the given
+   * face. It is not required that the normal vectors be normed
+   * somehow. Neither is it required that the normals actually point outward.
    *
-   * This function is
-   * needed to compute data for C1
-   * mappings. The default
-   * implementation is to throw an
-   * error, so you need not
-   * overload this function in case
-   * you do not intend to use C1
-   * mappings.
+   * This function is needed to compute data for C1 mappings. The default
+   * implementation is to throw an error, so you need not overload this
+   * function in case you do not intend to use C1 mappings.
    *
-   * Note that when computing
-   * normal vectors at a vertex
-   * where the boundary is not
-   * differentiable, you have to
-   * make sure that you compute the
-   * one-sided limits, i.e. limit
-   * with respect to points inside
-   * the given face.
+   * Note that when computing normal vectors at a vertex where the boundary is
+   * not differentiable, you have to make sure that you compute the one-sided
+   * limits, i.e. limit with respect to points inside the given face.
    */
   virtual
   void
@@ -331,35 +242,20 @@ public:
                            FaceVertexNormals &face_vertex_normals) const;
 
   /**
-   * Given a candidate point and a
-   * line segment characterized by
-   * the iterator, return a point
-   * that lies on the surface
-   * described by this object. This
-   * function is used in some mesh
-   * smoothing algorithms that try
-   * to move around points in order
-   * to improve the mesh quality
-   * but need to ensure that points
-   * that were on the boundary
-   * remain on the boundary.
+   * Given a candidate point and a line segment characterized by the iterator,
+   * return a point that lies on the surface described by this object. This
+   * function is used in some mesh smoothing algorithms that try to move
+   * around points in order to improve the mesh quality but need to ensure
+   * that points that were on the boundary remain on the boundary.
    *
-   * If spacedim==1, then the line
-   * represented by the line
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim==1, then the line represented by the line iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    *
-   * Derived classes do not need to
-   * implement this function unless
-   * mesh smoothing algorithms are
-   * used with a particular
-   * boundary object. The default
-   * implementation of this
-   * function throws an exception
-   * of type ExcPureFunctionCalled.
+   * Derived classes do not need to implement this function unless mesh
+   * smoothing algorithms are used with a particular boundary object. The
+   * default implementation of this function throws an exception of type
+   * ExcPureFunctionCalled.
    */
   virtual
   Point<spacedim>
@@ -367,19 +263,12 @@ public:
                       const Point<spacedim> &candidate) const;
 
   /**
-   * Same function as above but for
-   * a point that is to be
-   * projected onto the area
-   * characterized by the given
-   * quad.
+   * Same function as above but for a point that is to be projected onto the
+   * area characterized by the given quad.
    *
-   * If spacedim<=2, then the surface
-   * represented by the quad
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim<=2, then the surface represented by the quad iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    */
   virtual
   Point<spacedim>
@@ -387,24 +276,40 @@ public:
                       const Point<spacedim> &candidate) const;
 
   /**
-   * Same function as above but for
-   * a point that is to be
-   * projected onto the area
-   * characterized by the given
-   * quad.
+   * Same function as above but for a point that is to be projected onto the
+   * area characterized by the given quad.
    *
-   * If spacedim<=3, then the manifold
-   * represented by the hex
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim<=3, then the manifold represented by the hex iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    */
   virtual
   Point<spacedim>
   project_to_surface (const typename Triangulation<dim,spacedim>::hex_iterator &hex,
                       const Point<spacedim> &candidate) const;
+
+protected:
+  /**
+   * Returns the support points of the Gauss-Lobatto quadrature formula used
+   * for intermediate points.
+   *
+   * @note Since the boundary description is closely tied to the unit cell
+   * support points of MappingQ, new boundary descriptions need to explicitly
+   * use these Gauss-Lobatto points and not equidistant points.
+   */
+  const std::vector<Point<1> > &
+  get_line_support_points (const unsigned int n_intermediate_points) const;
+
+private:
+  /**
+   * Point generator for the intermediate points on a boundary.
+   */
+  mutable std::vector<std_cxx1x::shared_ptr<QGaussLobatto<1> > > points;
+
+  /**
+   * Mutex for protecting the points array.
+   */
+  mutable Threads::Mutex mutex;
 };
 
 
@@ -429,56 +334,37 @@ class StraightBoundary : public Boundary<dim,spacedim>
 {
 public:
   /**
-   * Default constructor. Some
-   * compilers require this for
-   * some reasons.
+   * Default constructor. Some compilers require this for some reasons.
    */
   StraightBoundary ();
 
   /**
-   * Let the new point be the
-   * arithmetic mean of the two
-   * vertices of the line.
+   * Let the new point be the arithmetic mean of the two vertices of the line.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class for more
-   * information.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class for more information.
    */
   virtual Point<spacedim>
   get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const;
 
   /**
-   * Let the new point be the
-   * arithmetic mean of the four
-   * vertices of this quad and the
-   * four midpoints of the lines,
-   * which are already created at
-   * the time of calling this
-   * function.
+   * Let the new point be the arithmetic mean of the four vertices of this
+   * quad and the four midpoints of the lines, which are already created at
+   * the time of calling this function.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class for more
-   * information.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class for more information.
    */
   virtual
   Point<spacedim>
   get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
 
   /**
-   * Gives <tt>n=points.size()</tt>
-   * points that splits the
-   * StraightBoundary line into
-   * $n+1$ partitions of equal
-   * lengths.
+   * Gives <tt>n=points.size()</tt> points that splits the StraightBoundary
+   * line into $n+1$ partitions of equal lengths.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class.
    */
   virtual
   void
@@ -486,16 +372,11 @@ public:
                                    std::vector<Point<spacedim> > &points) const;
 
   /**
-   * Gives <tt>n=points.size()=m*m</tt>
-   * points that splits the
-   * StraightBoundary quad into
-   * $(m+1)(m+1)$ subquads of equal
-   * size.
+   * Gives <tt>n=points.size()=m*m</tt> points that splits the
+   * StraightBoundary quad into $(m+1)(m+1)$ subquads of equal size.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class.
    */
   virtual
   void
@@ -503,13 +384,10 @@ public:
                                    std::vector<Point<spacedim> > &points) const;
 
   /**
-   * Implementation of the function
-   * declared in the base class.
+   * Implementation of the function declared in the base class.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class.
    */
   virtual
   Tensor<1,spacedim>
@@ -517,14 +395,10 @@ public:
                  const Point<spacedim> &p) const;
 
   /**
-   * Compute the normals to the
-   * boundary at the vertices of
-   * the given face.
+   * Compute the normals to the boundary at the vertices of the given face.
    *
-   * Refer to the general
-   * documentation of this class
-   * and the documentation of the
-   * base class.
+   * Refer to the general documentation of this class and the documentation of
+   * the base class.
    */
   virtual
   void
@@ -532,32 +406,18 @@ public:
                            typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const;
 
   /**
-   * Given a candidate point and a
-   * line segment characterized by
-   * the iterator, return a point
-   * that lies on the surface
-   * described by this object. This
-   * function is used in some mesh
-   * smoothing algorithms that try
-   * to move around points in order
-   * to improve the mesh quality
-   * but need to ensure that points
-   * that were on the boundary
-   * remain on the boundary.
+   * Given a candidate point and a line segment characterized by the iterator,
+   * return a point that lies on the surface described by this object. This
+   * function is used in some mesh smoothing algorithms that try to move
+   * around points in order to improve the mesh quality but need to ensure
+   * that points that were on the boundary remain on the boundary.
    *
-   * The point returned is the
-   * projection of the candidate
-   * point onto the line through
-   * the two vertices of the given
-   * line iterator.
+   * The point returned is the projection of the candidate point onto the line
+   * through the two vertices of the given line iterator.
    *
-   * If spacedim==1, then the line
-   * represented by the line
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim==1, then the line represented by the line iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    */
   virtual
   Point<spacedim>
@@ -565,26 +425,15 @@ public:
                       const Point<spacedim> &candidate) const;
 
   /**
-   * Same function as above but for
-   * a point that is to be
-   * projected onto the area
-   * characterized by the given
-   * quad.
+   * Same function as above but for a point that is to be projected onto the
+   * area characterized by the given quad.
    *
-   * The point returned is the
-   * projection of the candidate
-   * point onto the bilinear
-   * surface spanned by the four
-   * vertices of the given quad
-   * iterator.
+   * The point returned is the projection of the candidate point onto the
+   * bilinear surface spanned by the four vertices of the given quad iterator.
    *
-   * If spacedim<=2, then the surface
-   * represented by the quad
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim<=2, then the surface represented by the quad iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    */
   virtual
   Point<spacedim>
@@ -592,26 +441,16 @@ public:
                       const Point<spacedim> &candidate) const;
 
   /**
-   * Same function as above but for
-   * a point that is to be
-   * projected onto the area
-   * characterized by the given
-   * quad.
+   * Same function as above but for a point that is to be projected onto the
+   * area characterized by the given quad.
    *
-   * The point returned is the
-   * projection of the candidate
-   * point onto the trilinear
-   * manifold spanned by the eight
-   * vertices of the given hex
+   * The point returned is the projection of the candidate point onto the
+   * trilinear manifold spanned by the eight vertices of the given hex
    * iterator.
    *
-   * If spacedim<=3, then the manifold
-   * represented by the hex
-   * iterator is the entire space
-   * (i.e. it is a cell, not a part
-   * of the boundary), and the
-   * returned point equals the
-   * given input point.
+   * If spacedim<=3, then the manifold represented by the hex iterator is the
+   * entire space (i.e. it is a cell, not a part of the boundary), and the
+   * returned point equals the given input point.
    */
   virtual
   Point<spacedim>
index d077e4d8384ff4674b050d2e25816a5f9550cb51..cad63fdf4fed443acd1377e6969acde133a4c90d 100644 (file)
@@ -87,6 +87,25 @@ namespace internal
       const dealii::hp::FECollection<dim,FEValues::space_dimension> &
       get_fe_collection () const;
 
+      /**
+       * Get a reference to the collection of mapping objects used
+       * here.
+       */
+      const dealii::hp::MappingCollection<dim,FEValues::space_dimension> &
+      get_mapping_collection () const;
+
+      /**
+       * Get a reference to the collection of quadrature objects used
+       * here.
+       */
+      const dealii::hp::QCollection<q_dim> &
+      get_quadrature_collection () const;
+
+      /**
+       * Get the underlying update flags.
+       */
+      UpdateFlags get_update_flags() const;
+
       /**
        * Return a reference to the @p FEValues object selected by the last
        * call to select_fe_values(). select_fe_values() in turn is called when
@@ -592,6 +611,36 @@ namespace internal
     {
       return *fe_collection;
     }
+
+
+
+    template <int dim, int q_dim, class FEValues>
+    inline
+    const dealii::hp::MappingCollection<dim,FEValues::space_dimension> &
+    FEValuesBase<dim,q_dim,FEValues>::get_mapping_collection () const
+    {
+      return *mapping_collection;
+    }
+
+
+
+    template <int dim, int q_dim, class FEValues>
+    inline
+    const dealii::hp::QCollection<q_dim> &
+    FEValuesBase<dim,q_dim,FEValues>::get_quadrature_collection () const
+    {
+      return q_collection;
+    }
+
+
+
+    template <int dim, int q_dim, class FEValues>
+    inline
+    dealii::UpdateFlags
+    FEValuesBase<dim,q_dim,FEValues>::get_update_flags () const
+    {
+      return update_flags;
+    }
   }
 
 }
index c20eb4beba3f10483f71851f94addd5c873a7817..fd9564c3742b4876a68b68a0218a21b56e10168d 100644 (file)
@@ -349,6 +349,77 @@ namespace LocalIntegrators
         }
     }
 
+    template <int dim>
+    void ip_tangential_matrix (
+      FullMatrix<double> &M11,
+      FullMatrix<double> &M12,
+      FullMatrix<double> &M21,
+      FullMatrix<double> &M22,
+      const FEValuesBase<dim> &fe1,
+      const FEValuesBase<dim> &fe2,
+      double penalty,
+      double factor1 = 1.,
+      double factor2 = -1.)
+    {
+      const unsigned int n_dofs = fe1.dofs_per_cell;
+      AssertDimension(fe1.get_fe().n_components(), dim);
+      AssertDimension(fe2.get_fe().n_components(), dim);
+      AssertDimension(M11.n(), n_dofs);
+      AssertDimension(M11.m(), n_dofs);
+      AssertDimension(M12.n(), n_dofs);
+      AssertDimension(M12.m(), n_dofs);
+      AssertDimension(M21.n(), n_dofs);
+      AssertDimension(M21.m(), n_dofs);
+      AssertDimension(M22.n(), n_dofs);
+      AssertDimension(M22.m(), n_dofs);
+
+      const double nui = factor1;
+      const double nue = (factor2 < 0) ? factor1 : factor2;
+      const double nu = .5*(nui+nue);
+
+      for (unsigned int k=0; k<fe1.n_quadrature_points; ++k)
+        {
+          const double dx = fe1.JxW(k);
+          const Point<dim> &n = fe1.normal_vector(k);
+         for (unsigned int i=0; i<n_dofs; ++i)
+           {
+             for (unsigned int j=0; j<n_dofs; ++j)
+               {
+                 double u1dotn = 0.;
+                 double v1dotn = 0.;
+                 double u2dotn = 0.;
+                 double v2dotn = 0.;
+                 
+                 for (unsigned int d=0; d<dim; ++d)
+                   {
+                     u1dotn += n(d)*fe1.shape_value_component(j,k,d);
+                     v1dotn += n(d)*fe1.shape_value_component(i,k,d);
+                     u2dotn += n(d)*fe2.shape_value_component(j,k,d);
+                     v2dotn += n(d)*fe2.shape_value_component(i,k,d);
+                   }
+                         
+                 for (unsigned int d=0; d<fe1.get_fe().n_components(); ++d)
+                   {
+                     
+                                                      // multiply by 
+                      const double vi = fe1.shape_value_component(i,k,d)*(1-v1dotn);
+                      const double dnvi = n * fe1.shape_grad_component(i,k,d)*(1-v1dotn);
+                      const double ve = fe2.shape_value_component(i,k,d)*(1-v2dotn);
+                      const double dnve = n * fe2.shape_grad_component(i,k,d)*(1-v2dotn);
+                      const double ui = fe1.shape_value_component(j,k,d)*(1-u1dotn);
+                      const double dnui = n * fe1.shape_grad_component(j,k,d)*(1-u1dotn);
+                      const double ue = fe2.shape_value_component(j,k,d)*(1-u2dotn);
+                      const double dnue = n * fe2.shape_grad_component(j,k,d)*(1-u2dotn);
+                      M11(i,j) += dx*(-.5*nui*dnvi*ui-.5*nui*dnui*vi+nu*penalty*ui*vi);
+                      M12(i,j) += dx*( .5*nui*dnvi*ue-.5*nue*dnue*vi-nu*penalty*vi*ue);
+                      M21(i,j) += dx*(-.5*nue*dnve*ui+.5*nui*dnui*ve-nu*penalty*ui*ve);
+                      M22(i,j) += dx*( .5*nue*dnve*ue+.5*nue*dnue*ve+nu*penalty*ue*ve);
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Residual term for the symmetric interior penalty method.
      *
index 6c623eef0ed0c17af3261de671b0a037c138f765..7d5ae2e78bf28db6d76ef814d4d7033aa6896e73 100644 (file)
@@ -233,6 +233,14 @@ public:
    */
   bool can_store_line (const size_type line_index) const;
 
+  /**
+   * Returns the index set describing locally relevant lines if any are
+   * present. Note that if no local lines were given, this represents an empty
+   * IndexSet, whereas otherwise it contains the global problem size and the
+   * local range.
+   */
+  const IndexSet & get_local_lines() const;
+
   /**
    * This function copies the content of @p
    * constraints_in with DoFs that are
@@ -2050,6 +2058,15 @@ ConstraintMatrix::can_store_line (size_type line_index) const
 
 
 
+inline
+const IndexSet &
+ConstraintMatrix::get_local_lines () const
+{
+  return local_lines;
+}
+
+
+
 template <class VectorType>
 inline
 void ConstraintMatrix::distribute_local_to_global (
index 509297a5742a2c54add04acacfa850c47d7c504e..184164369d794c371cb022e67135726dac6d5b9e 100644 (file)
@@ -119,11 +119,6 @@ namespace SLEPcWrappers
   class SolverBase
   {
   public:
-    /**
-     * Declare type for container size.
-     */
-    typedef types::global_dof_index size_type;
-
     /**
      * Constructor. Takes the MPI communicator over which parallel
      * computations are to happen.
@@ -161,7 +156,7 @@ namespace SLEPcWrappers
     solve (const PETScWrappers::MatrixBase &A,
            std::vector<double>             &eigenvalues,
            std::vector<OutputVector>       &eigenvectors,
-           const size_type                  n_eigenpairs = 1);
+           const unsigned int               n_eigenpairs = 1);
 
     /**
      * Same as above, but here a composite method for solving the
@@ -174,7 +169,7 @@ namespace SLEPcWrappers
            const PETScWrappers::MatrixBase &B,
            std::vector<double>             &eigenvalues,
            std::vector<OutputVector>       &eigenvectors,
-           const size_type                  n_eigenpairs = 1);
+           const unsigned int               n_eigenpairs = 1);
 
     /**
      * Same as above, but here a composite method for solving the
@@ -299,12 +294,13 @@ namespace SLEPcWrappers
     /**
      * Solve the linear system for <code>n_eigenpairs</code>
      * eigenstates. Parameter <code>n_converged</code> contains the
-     * actual number of eigenstates that have  converged; this can
+     * actual number of eigenstates that have  converged; this can
      * be both fewer or more than n_eigenpairs, depending on the
      * SLEPc eigensolver used.
      */
     void
-    solve (const unsigned int n_eigenpairs, unsigned int *n_converged);
+    solve (const unsigned int n_eigenpairs,
+          unsigned int *n_converged);
 
     /**
      * Access the real parts of solutions for a solved eigenvector
@@ -754,7 +750,7 @@ namespace SLEPcWrappers
   SolverBase::solve (const PETScWrappers::MatrixBase &A,
                      std::vector<double>             &eigenvalues,
                      std::vector<OutputVector>       &eigenvectors,
-                     const size_type                  n_eigenpairs)
+                     const unsigned int               n_eigenpairs)
   {
     // Panic if the number of eigenpairs wanted is out of bounds.
     AssertThrow ((n_eigenpairs > 0) && (n_eigenpairs <= A.m ()),
@@ -764,7 +760,7 @@ namespace SLEPcWrappers
     set_matrices (A);
 
     // and solve
-    size_type n_converged = 0;
+    unsigned int n_converged = 0;
     solve (n_eigenpairs, &n_converged);
 
     if (n_converged > n_eigenpairs)
@@ -776,7 +772,7 @@ namespace SLEPcWrappers
     eigenvectors.resize (n_converged, eigenvectors.front());
     eigenvalues.resize (n_converged);
 
-    for (size_type index=0; index<n_converged; ++index)
+    for (unsigned int index=0; index<n_converged; ++index)
       get_eigenpair (index, eigenvalues[index], eigenvectors[index]);
   }
 
@@ -786,7 +782,7 @@ namespace SLEPcWrappers
                      const PETScWrappers::MatrixBase &B,
                      std::vector<double>             &eigenvalues,
                      std::vector<OutputVector>       &eigenvectors,
-                     const size_type                  n_eigenpairs)
+                     const unsigned int                  n_eigenpairs)
   {
     // Guard against incompatible matrix sizes:
     AssertThrow (A.m() == B.m (), ExcDimensionMismatch(A.m(), B.m()));
@@ -800,7 +796,7 @@ namespace SLEPcWrappers
     set_matrices (A, B);
 
     // and solve
-    size_type n_converged = 0;
+    unsigned int n_converged = 0;
     solve (n_eigenpairs, &n_converged);
 
     if (n_converged>=n_eigenpairs)
@@ -813,7 +809,7 @@ namespace SLEPcWrappers
     eigenvectors.resize (n_converged, eigenvectors.front());
     eigenvalues.resize (n_converged);
 
-    for (size_type index=0; index<n_converged; ++index)
+    for (unsigned int index=0; index<n_converged; ++index)
       get_eigenpair (index, eigenvalues[index], eigenvectors[index]);
   }
 
@@ -825,7 +821,7 @@ namespace SLEPcWrappers
                      std::vector<double>             &imag_eigenvalues,
                      std::vector<OutputVector>       &real_eigenvectors,
                      std::vector<OutputVector>       &imag_eigenvectors,
-                     const size_type                  n_eigenpairs)
+                     const unsigned int                  n_eigenpairs)
   {
     // Guard against incompatible matrix sizes:
     AssertThrow (A.m() == B.m (), ExcDimensionMismatch(A.m(), B.m()));
@@ -845,7 +841,7 @@ namespace SLEPcWrappers
     set_matrices (A, B);
 
     // and solve
-    size_type n_converged = 0;
+    unsigned int n_converged = 0;
     solve (n_eigenpairs, &n_converged);
 
     if (n_converged>=n_eigenpairs)
@@ -861,7 +857,7 @@ namespace SLEPcWrappers
     real_eigenvalues.resize (n_converged);
     imag_eigenvalues.resize (n_converged);
 
-    for (size_type index=0; index<n_converged; ++index)
+    for (unsigned int index=0; index<n_converged; ++index)
       get_eigenpair (index,
                      real_eigenvalues[index], imag_eigenvalues[index],
                      real_eigenvectors[index], imag_eigenvectors[index]);
index 4323bbf83a7a2d02e5ecac47f64bdeb6abbf5617..1bd8c63b5c4642674fcaf5dc96b953f91df385b7 100644 (file)
@@ -90,44 +90,30 @@ namespace MeshWorker
     IntegrationInfo();
 
     /**
-     * Copy constructor, creating a
-     * clone to be used by
+     * Copy constructor, creating a clone to be used by
      * WorksTream::run().
      */
     IntegrationInfo(const IntegrationInfo<dim, spacedim> &other);
 
     /**
-     * Build all internal
-     * structures, in particular
-     * the FEValuesBase objects
-     * and allocate space for
-     * data vectors.
+     * Build all internal structures, in particular the FEValuesBase
+     * objects and allocate space for data vectors.
      *
-     * @param el is the finite
-     * element of the DoFHandler.
+     * @param el is the finite element of the DoFHandler.
      *
-     * @param mapping is the Mapping
-     * object used to map the
-     * mesh cells.
+     * @param mapping is the Mapping object used to map the mesh
+     * cells.
      *
-     * @param quadrature is a
-     * Quadrature formula used in
-     * the constructor of the
-     * FEVALUES objects.
+     * @param quadrature is a Quadrature formula used in the
+     * constructor of the FEVALUES objects.
      *
-     * @param flags are the
-     * UpdateFlags used in
-     * the constructor of the
+     * @param flags are the UpdateFlags used in the constructor of the
      * FEVALUES objects.
      *
-     * @param local_block_info is
-     * an optional parameter for
-     * systems of PDE. If it is
-     * provided with reasonable
-     * data, then the degrees of
-     * freedom on the cells will be
-     * re-ordered to reflect the
-     * block structure of the system.
+     * @param local_block_info is an optional parameter for systems of
+     * PDE. If it is provided with reasonable data, then the degrees
+     * of freedom on the cells will be re-ordered to reflect the block
+     * structure of the system.
      */
     template <class FEVALUES>
     void initialize(const FiniteElement<dim,spacedim> &el,
@@ -137,9 +123,7 @@ namespace MeshWorker
                     const BlockInfo *local_block_info = 0);
 
     /**
-     * Initialize the data
-     * vector and cache the
-     * selector.
+     * Initialize the data vector and cache the selector.
      */
     void initialize_data(const std_cxx1x::shared_ptr<VectorDataBase<dim,spacedim> > &data);
 
@@ -152,97 +136,67 @@ namespace MeshWorker
     bool multigrid;
     /// Access to finite element
     /**
-     * This is the access
-     * function being used, if
-     * the constructor for a
-     * single element was
-     * used. It throws an
-     * exception, if applied to a
-     * vector of elements.
+     * This is the access function being used, if the constructor for
+     * a single element was used. It throws an exception, if applied
+     * to a vector of elements.
      */
     const FEValuesBase<dim, spacedim> &fe_values () const;
 
     /// Access to finite elements
     /**
-     * This access function must
-     * be used if the constructor
-     * for a group of elements
-     * was used.
+     * This access function must be used if the constructor for a
+     * group of elements was used.
      *
      * @see DGBlockSplitApplication
      */
     const FEValuesBase<dim, spacedim> &fe_values (const unsigned int i) const;
 
     /**
-     * The vector containing the
-     * values of finite element
-     * functions in the quadrature
-     * points.
+     * The vector containing the values of finite element functions in
+     * the quadrature points.
      *
-     * There is one vector per
-     * selected finite element
-     * function, containing one
-     * vector for each component,
-     * containing vectors with
-     * values for each quadrature
-     * point.
+     * There is one vector per selected finite element function,
+     * containing one vector for each component, containing vectors
+     * with values for each quadrature point.
      */
     std::vector<std::vector<std::vector<double> > > values;
 
     /**
-     * The vector containing the
-     * derivatives of finite
-     * element functions in the
-     * quadrature points.
+     * The vector containing the derivatives of finite element
+     * functions in the quadrature points.
      *
-     * There is one vector per
-     * selected finite element
-     * function, containing one
-     * vector for each component,
-     * containing vectors with
-     * values for each quadrature
-     * point.
+     * There is one vector per selected finite element function,
+     * containing one vector for each component, containing vectors
+     * with values for each quadrature point.
      */
     std::vector<std::vector<std::vector<Tensor<1,dim> > > > gradients;
 
     /**
-     * The vector containing the
-     * second derivatives of finite
-     * element functions in the
-     * quadrature points.
+     * The vector containing the second derivatives of finite element
+     * functions in the quadrature points.
      *
-     * There is one vector per
-     * selected finite element
-     * function, containing one
-     * vector for each component,
-     * containing vectors with
-     * values for each quadrature
-     * point.
+     * There is one vector per selected finite element function,
+     * containing one vector for each component, containing vectors
+     * with values for each quadrature point.
      */
     std::vector<std::vector<std::vector<Tensor<2,dim> > > > hessians;
 
     /**
-     * Reinitialize internal data
-     * structures for use on a cell.
+     * Reinitialize internal data structures for use on a cell.
      */
     template <typename number>
     void reinit(const DoFInfo<dim, spacedim, number> &i);
 
     /**
-     * Use the finite element
-     * functions in #global_data
-     * and fill the vectors
-     * #values, #gradients and
-     * #hessians.
+     * Use the finite element functions in #global_data and fill the
+     * vectors #values, #gradients and #hessians.
      */
     template<typename number>
     void fill_local_data(const DoFInfo<dim, spacedim, number> &info, bool split_fevalues);
 
     /**
-     * The global data vector
-     * used to compute function
-     * values in quadrature
-     * points.
+     * The global data vector used to compute function values in
+     * quadrature points.
      */
     std_cxx1x::shared_ptr<VectorDataBase<dim, spacedim> > global_data;
 
@@ -253,13 +207,9 @@ namespace MeshWorker
 
   private:
     /**
-     * Use the finite element
-     * functions in #global_data
-     * and fill the vectors
-     * #values, #gradients and
-     * #hessians with values
-     * according to the
-     * selector.
+     * Use the finite element functions in #global_data and fill the
+     * vectors #values, #gradients and #hessians with values according
+     * to the selector.
      */
     template <typename TYPE>
     void fill_local_data(
@@ -267,8 +217,7 @@ namespace MeshWorker
       VectorSelector &selector,
       bool split_fevalues) const;
     /**
-     * Cache the number of
-     * components of the system element.
+     * Cache the number of components of the system element.
      */
     unsigned int n_components;
   };
@@ -346,34 +295,22 @@ namespace MeshWorker
     IntegrationInfoBox ();
 
     /**
-     * Initialize the
-     * IntegrationInfo objects
-     * contained.
+     * Initialize the IntegrationInfo objects contained.
      *
-     * Before doing so, add update
-     * flags necessary to produce
-     * the data needed and also
-     * set uninitialized quadrature
-     * rules to Gauss formulas,
-     * which integrate polynomial
-     * bilinear forms exactly.
+     * Before doing so, add update flags necessary to produce the data
+     * needed and also set uninitialized quadrature rules to Gauss
+     * formulas, which integrate polynomial bilinear forms exactly.
      */
     void initialize(const FiniteElement<dim, spacedim> &el,
                     const Mapping<dim, spacedim> &mapping,
                     const BlockInfo *block_info = 0);
 
     /**
-     * Initialize the
-     * IntegrationInfo objects
-     * contained.
+     * Initialize the IntegrationInfo objects contained.
      *
-     * Before doing so, add update
-     * flags necessary to produce
-     * the data needed and also
-     * set uninitialized quadrature
-     * rules to Gauss formulas,
-     * which integrate polynomial
-     * bilinear forms exactly.
+     * Before doing so, add update flags necessary to produce the data
+     * needed and also set uninitialized quadrature rules to Gauss
+     * formulas, which integrate polynomial bilinear forms exactly.
      */
     template <typename VECTOR>
     void initialize(const FiniteElement<dim, spacedim> &el,
@@ -382,17 +319,11 @@ namespace MeshWorker
                     const BlockInfo *block_info = 0);
 
     /**
-     * Initialize the
-     * IntegrationInfo objects
-     * contained.
+     * Initialize the IntegrationInfo objects contained.
      *
-     * Before doing so, add update
-     * flags necessary to produce
-     * the data needed and also
-     * set uninitialized quadrature
-     * rules to Gauss formulas,
-     * which integrate polynomial
-     * bilinear forms exactly.
+     * Before doing so, add update flags necessary to produce the data
+     * needed and also set uninitialized quadrature rules to Gauss
+     * formulas, which integrate polynomial bilinear forms exactly.
      */
     template <typename VECTOR>
     void initialize(const FiniteElement<dim, spacedim> &el,
@@ -405,64 +336,43 @@ namespace MeshWorker
     /* @{ */
 
     /**
-    * Call this function before
-    * initialize() in order to
-    * guess the update flags
-    * needed, based on the data
-    * selected.
+    * Call this function before initialize() in order to guess the
+    * update flags needed, based on the data selected.
     *
-    * When computing face fluxes,
-    * we normally can use the
-    * geometry (integration
-    * weights and normal vectors)
-    * from the original cell and
-    * thus can avoid updating
-    * these values on the
-    * neighboring cell. Set
-    * <tt>neighbor_geometry</tt>
-    * to true in order to
-    * initialize these values as
-    * well.
+    * When computing face fluxes, we normally can use the geometry
+    * (integration weights and normal vectors) from the original cell
+    * and thus can avoid updating these values on the neighboring
+    * cell. Set <tt>neighbor_geometry</tt> to true in order to
+    * initialize these values as well.
     */
     void initialize_update_flags(bool neighbor_geometry = false);
 
     /**
-     * Add FEValues UpdateFlags for
-     * integration on all objects
-     * (cells, boundary faces and
-     * all interior faces).
+     * Add FEValues UpdateFlags for integration on all objects (cells,
+     * boundary faces and all interior faces).
      */
     void add_update_flags_all (const UpdateFlags flags);
 
     /**
-     * Add FEValues UpdateFlags for
-     * integration on cells.
+     * Add FEValues UpdateFlags for integration on cells.
      */
     void add_update_flags_cell(const UpdateFlags flags);
 
     /**
-     * Add FEValues UpdateFlags for
-     * integration on boundary faces.
+     * Add FEValues UpdateFlags for integration on boundary faces.
      */
     void add_update_flags_boundary(const UpdateFlags flags);
 
     /**
-     * Add FEValues UpdateFlags for
-     * integration on interior faces.
+     * Add FEValues UpdateFlags for integration on interior faces.
      */
     void add_update_flags_face(const UpdateFlags flags);
 
     /**
-     * Add additional update flags
-     * to the ones already set in
-     * this program. The four
-     * boolean flags indicate
-     * whether the additional flags
-     * should be set for cell,
-     * boundary, interelement face
-     * for the cell itself
-     * or neighbor cell, or
-     * any combination thereof.
+     * Add additional update flags to the ones already set in this
+     * program. The four boolean flags indicate whether the additional
+     * flags should be set for cell, boundary, interelement face for
+     * the cell itself or neighbor cell, or any combination thereof.
      */
     void add_update_flags(const UpdateFlags flags,
                           const bool cell = true,
@@ -471,19 +381,12 @@ namespace MeshWorker
                           const bool neighbor = true);
 
     /**
-     * Assign n-point Gauss
-     * quadratures to each of the
-     * quadrature rules. Here, a
-     * size of zero points means
-     * that no loop over these grid
-     * entities should be
-     * performed.
+     * Assign n-point Gauss quadratures to each of the quadrature
+     * rules. Here, a size of zero points means that no loop over
+     * these grid entities should be performed.
      *
-     * If the parameter
-     * <tt>force</tt> is true, then
-     * all quadrature sets are
-     * filled with new quadrature
-     * ruels. If it is false, then
+     * If the parameter <tt>force</tt> is true, then all quadrature
+     * sets are filled with new quadrature ruels. If it is false, then
      * only empty rules are changed.
      */
     void initialize_gauss_quadrature(unsigned int n_cell_points,
@@ -497,59 +400,45 @@ namespace MeshWorker
     std::size_t memory_consumption () const;
 
     /**
-     * The set of update flags
-     * for boundary cell integration.
+     * The set of update flags for boundary cell integration.
      *
-     * Defaults to
-     * #update_JxW_values.
+     * Defaults to #update_JxW_values.
      */
     UpdateFlags cell_flags;
     /**
-     * The set of update flags
-     * for boundary face integration.
+     * The set of update flags for boundary face integration.
      *
-     * Defaults to
-     * #update_JxW_values and
-     * #update_normal_vectors.
+     * Defaults to #update_JxW_values and #update_normal_vectors.
      */
     UpdateFlags boundary_flags;
 
     /**
-     * The set of update flags
-     * for interior face integration.
+     * The set of update flags for interior face integration.
      *
-     * Defaults to
-     * #update_JxW_values and
-     * #update_normal_vectors.
+     * Defaults to #update_JxW_values and #update_normal_vectors.
      */
     UpdateFlags face_flags;
 
     /**
-     * The set of update flags
-     * for interior face integration.
+     * The set of update flags for interior face integration.
      *
-     * Defaults to
-     * #update_default, since
-     * quadrature weights are
-     * taken from the other cell.
+     * Defaults to #update_default, since quadrature weights are taken
+     * from the other cell.
      */
     UpdateFlags neighbor_flags;
 
     /**
-     * The quadrature rule used
-     * on cells.
+     * The quadrature rule used on cells.
      */
     Quadrature<dim> cell_quadrature;
 
     /**
-     * The quadrature rule used
-     * on boundary faces.
+     * The quadrature rule used on boundary faces.
      */
     Quadrature<dim-1> boundary_quadrature;
 
     /**
-     * The quadrature rule used
-     * on interior faces.
+     * The quadrature rule used on interior faces.
      */
     Quadrature<dim-1> face_quadrature;
     /* @} */
@@ -560,46 +449,30 @@ namespace MeshWorker
     /* @{ */
 
     /**
-     * Initialize the
-     * VectorSelector objects
-     * #cell_selector,
-     * #boundary_selector and
-     * #face_selector in order to
-     * save computational
-     * effort. If no selectors
-     * are used, then values for
-     * all named vectors in
-     * DoFInfo::global_data will be
-     * computed in all quadrature
-     * points.
+     * Initialize the VectorSelector objects #cell_selector,
+     * #boundary_selector and #face_selector in order to save
+     * computational effort. If no selectors are used, then values for
+     * all named vectors in DoFInfo::global_data will be computed in
+     * all quadrature points.
      *
-     * This function will also
-     * add UpdateFlags to the
-     * flags stored in this class.
+     * This function will also add UpdateFlags to the flags stored in
+     * this class.
      */
     /**
-     * Select the vectors from
-     * DoFInfo::global_data
-     * that should be computed in
-     * the quadrature points on cells.
+     * Select the vectors from DoFInfo::global_data that should be
+     * computed in the quadrature points on cells.
      */
     MeshWorker::VectorSelector cell_selector;
 
     /**
-     * Select the vectors from
-     * DoFInfo::global_data
-     * that should be computed in
-     * the quadrature points on
-     * boundary faces.
+     * Select the vectors from DoFInfo::global_data that should be
+     * computed in the quadrature points on boundary faces.
      */
     MeshWorker::VectorSelector boundary_selector;
 
     /**
-     * Select the vectors from
-     * DoFInfo::global_data
-     * that should be computed in
-     * the quadrature points on
-     * interior faces.
+     * Select the vectors from DoFInfo::global_data that should be
+     * computed in the quadrature points on interior faces.
      */
     MeshWorker::VectorSelector face_selector;
 
@@ -613,68 +486,41 @@ namespace MeshWorker
      */
     /* @{ */
     /**
-     * A callback function which is
-     * called in the loop over all
-     * cells, after the action on a
-     * cell has been performed and
-     * before the faces are dealt
-     * with.
+     * A callback function which is called in the loop over all cells,
+     * after the action on a cell has been performed and before the
+     * faces are dealt with.
      *
-     * In order for this function
-     * to have this effect,
-     * at least either of the
-     * arguments
-     * <tt>boundary_worker</tt> or
-     * <tt>face_worker</tt>
-     * arguments of loop() should
-     * be nonzero. Additionally,
-     * <tt>cells_first</tt> should
-     * be true. If
-     * <tt>cells_first</tt> is
-     * false, this function is
-     * called before any action on
-     * a cell is taken.
+     * In order for this function to have this effect, at least either
+     * of the arguments <tt>boundary_worker</tt> or
+     * <tt>face_worker</tt> arguments of loop() should be
+     * nonzero. Additionally, <tt>cells_first</tt> should be true. If
+     * <tt>cells_first</tt> is false, this function is called before
+     * any action on a cell is taken.
      *
-     * And empty function in this
-     * class, but can be replaced
-     * in other classes given to
-     * loop() instead.
+     * And empty function in this class, but can be replaced in other
+     * classes given to loop() instead.
      *
-     * See loop() and cell_action()
-     * for more details of how this
+     * See loop() and cell_action() for more details of how this
      * function can be used.
      */
     template <class DOFINFO>
     void post_cell(const DoFInfoBox<dim, DOFINFO> &);
 
     /**
-     * A callback function which is
-     * called in the loop over all
-     * cells, after the action on
-     * the faces of a cell has been
-     * performed and before the
-     * cell itself is dealt with
-     * (assumes
+     * A callback function which is called in the loop over all cells,
+     * after the action on the faces of a cell has been performed and
+     * before the cell itself is dealt with (assumes
      * <tt>cells_first</tt> is false).
      *
-     * In order for this function
-     * to have a reasonable effect,
-     * at least either of the
-     * arguments
-     * <tt>boundary_worker</tt> or
-     * <tt>face_worker</tt>
-     * arguments of loop() should
-     * be nonzero. Additionally,
-     * <tt>cells_first</tt> should
-     * be false.
+     * In order for this function to have a reasonable effect, at
+     * least either of the arguments <tt>boundary_worker</tt> or
+     * <tt>face_worker</tt> arguments of loop() should be
+     * nonzero. Additionally, <tt>cells_first</tt> should be false.
      *
-     * And empty function in this
-     * class, but can be replaced
-     * in other classes given to
-     * loop() instead.
+     * And empty function in this class, but can be replaced in other
+     * classes given to loop() instead.
      *
-     * See loop() and cell_action()
-     * for more details of how this
+     * See loop() and cell_action() for more details of how this
      * function can be used.
      */
     template <class DOFINFO>
@@ -685,27 +531,21 @@ namespace MeshWorker
      */
     CellInfo cell;
     /**
-     * The info object for a
-     * boundary face.
+     * The info object for a boundary face.
      */
     CellInfo boundary;
     /**
-     * The info object for a
-     * regular interior face, seen
-     * from the first cell.
+     * The info object for a regular interior face, seen from the
+     * first cell.
      */
     CellInfo face;
     /**
-     * The info object for the
-     * refined side of an interior
-     * face seen from the first
-     * cell.
+     * The info object for the refined side of an interior face seen
+     * from the first cell.
      */
     CellInfo subface;
     /**
-     * The info object for an
-     * interior face, seen from the
-     * other cell.
+     * The info object for an interior face, seen from the other cell.
      */
     CellInfo neighbor;
 
index 88e201777a49df2117480e7d9b2f8e1f68733763..e43257df1566aa2f821c7c5ff30dd8cb1c58b987 100644 (file)
@@ -256,29 +256,24 @@ namespace MeshWorker
     {
     public:
       /**
-       * Constructor, initializing
-       * the #threshold, which
-       * limits how small numbers
-       * may be to be entered into
-       * the matrix.
+       * Constructor, initializing the #threshold, which limits how
+       * small numbers may be to be entered into the matrix.
        */
       MGMatrixSimple(double threshold = 1.e-12);
 
       /**
-       * Store the result matrix
-       * for later assembling.
+       * Store the result matrix for later assembling.
        */
       void initialize(MGLevelObject<MATRIX> &m);
 
       /**
-       * Initialize the multilevel
-       * constraints.
+       * Initialize the multilevel constraints.
        */
       void initialize(const MGConstrainedDoFs &mg_constrained_dofs);
 
       /**
-       * @deprecated This function is of no effect. Only the block info
-       * structure in DoFInfo is being used.
+       * @deprecated This function is of no effect. Only the block
+       * info structure in DoFInfo is being used.
        *
        * Store information on the local block structure. If the
        * assembler is inititialized with this function,
@@ -458,6 +453,15 @@ namespace MeshWorker
        */
       void initialize(MATRIX &m, VECTOR &rhs);
 
+      /**
+       * Initialize the constraints. After this function has been
+       * called with a valid ConstraintMatrix, the function
+       * ConstraintMatrix::distribute_local_to_global() will be used
+       * by assemble() to distribute the cell and face matrices into a
+       * global sparse matrix.
+       */
+      void initialize(const ConstraintMatrix &constraints);
+
       /**
        * Initialize the local data
        * in the
@@ -911,8 +915,7 @@ namespace MeshWorker
           for (unsigned int j=0; j<i1.size(); ++j)
             for (unsigned int k=0; k<i2.size(); ++k)
               if (std::fabs(M(k,j)) >= threshold)
-                if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
-                    !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
+               if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
                   G.add(i1[j], i2[k], M(k,j));
         }
     }
@@ -941,8 +944,7 @@ namespace MeshWorker
           for (unsigned int j=0; j<i1.size(); ++j)
             for (unsigned int k=0; k<i2.size(); ++k)
               if (std::fabs(M(j,k)) >= threshold)
-                if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
-                    !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
+                if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
                   G.add(i1[j], i2[k], M(j,k));
         }
     }
@@ -958,49 +960,41 @@ namespace MeshWorker
     {
       AssertDimension(M.m(), i1.size());
       AssertDimension(M.n(), i2.size());
-
-      if (mg_constrained_dofs == 0)
-        {
-          for (unsigned int j=0; j<i1.size(); ++j)
-            for (unsigned int k=0; k<i2.size(); ++k)
-              if (std::fabs(M(j,k)) >= threshold)
-                G.add(i1[j], i2[k], M(j,k));
-        }
-      else
-        {
-          for (unsigned int j=0; j<i1.size(); ++j)
-            for (unsigned int k=0; k<i2.size(); ++k)
-              if (std::fabs(M(j,k)) >= threshold)
-                // Enter values into matrix only if j corresponds to a
-                // degree of freedom on the refinemenent edge, k does
-                // not, and both are not on the boundary. This is part
-                // the difference between the complete matrix with no
-                // boundary condition at the refinement edge and and
-                // the matrix assembled above by assemble().
-
-                // Thus the logic is: enter the row if it is
-                // constrained by hanging node constraints (actually,
-                // the whole refinement edge), but not if it is
-                // constrained by a boundary constraint.
-                if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
-                    !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
-                  {
-                    if (mg_constrained_dofs->set_boundary_values())
-                      {
-                        if ((!mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
-                             !mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]))
-                            ||
-                            (mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
-                             mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]) &&
-                             i1[j] == i2[k]))
-                          G.add(i1[j], i2[k], M(j,k));
-                      }
-                    else
-                      G.add(i1[j], i2[k], M(j,k));
-                  }
-        }
+      Assert(mg_constrained_dofs != 0, ExcInternalError());
+      
+      for (unsigned int j=0; j<i1.size(); ++j)
+       for (unsigned int k=0; k<i2.size(); ++k)
+         if (std::fabs(M(j,k)) >= threshold)
+                                            // Enter values into matrix only if j corresponds to a
+                                            // degree of freedom on the refinemenent edge, k does
+                                            // not, and both are not on the boundary. This is part
+                                            // the difference between the complete matrix with no
+                                            // boundary condition at the refinement edge and and
+                                            // the matrix assembled above by assemble().
+           
+                                            // Thus the logic is: enter the row if it is
+                                            // constrained by hanging node constraints (actually,
+                                            // the whole refinement edge), but not if it is
+                                            // constrained by a boundary constraint.
+           if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
+               !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
+             {
+               if (mg_constrained_dofs->set_boundary_values())
+                 {
+                   if ((!mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
+                        !mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]))
+                       ||
+                       (mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
+                        mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]) &&
+                        i1[j] == i2[k]))
+                     G.add(i1[j], i2[k], M(j,k));
+                 }
+               else
+                 G.add(i1[j], i2[k], M(j,k));
+             }
     }
-
+    
+    
     template <class MATRIX>
     inline void
     MGMatrixSimple<MATRIX>::assemble_out(
@@ -1012,38 +1006,29 @@ namespace MeshWorker
     {
       AssertDimension(M.n(), i1.size());
       AssertDimension(M.m(), i2.size());
-
-      if (mg_constrained_dofs == 0)
-        {
-          for (unsigned int j=0; j<i1.size(); ++j)
-            for (unsigned int k=0; k<i2.size(); ++k)
-              if (std::fabs(M(k,j)) >= threshold)
-                G.add(i1[j], i2[k], M(k,j));
-        }
-      else
-        {
-          for (unsigned int j=0; j<i1.size(); ++j)
-            for (unsigned int k=0; k<i2.size(); ++k)
-              if (std::fabs(M(k,j)) >= threshold)
-                if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
-                    !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
-                  {
-                    if (mg_constrained_dofs->set_boundary_values())
-                      {
-                        if ((!mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
-                             !mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]))
-                            ||
-                            (mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
-                             mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]) &&
-                             i1[j] == i2[k]))
-                          G.add(i1[j], i2[k], M(k,j));
-                      }
-                    else
-                      G.add(i1[j], i2[k], M(k,j));
-                  }
-        }
+      Assert(mg_constrained_dofs != 0, ExcInternalError());
+      
+      for (unsigned int j=0; j<i1.size(); ++j)
+       for (unsigned int k=0; k<i2.size(); ++k)
+         if (std::fabs(M(k,j)) >= threshold)
+           if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
+               !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
+             {
+               if (mg_constrained_dofs->set_boundary_values())
+                 {
+                   if ((!mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
+                        !mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]))
+                       ||
+                       (mg_constrained_dofs->at_refinement_edge_boundary(level, i1[j]) &&
+                        mg_constrained_dofs->at_refinement_edge_boundary(level, i2[k]) &&
+                        i1[j] == i2[k]))
+                     G.add(i1[j], i2[k], M(k,j));
+                 }
+               else
+                 G.add(i1[j], i2[k], M(k,j));
+             }
     }
-
+  
 
     template <class MATRIX>
     template <class DOFINFO>
@@ -1189,7 +1174,15 @@ namespace MeshWorker
       ResidualSimple<VECTOR>::initialize(data);
     }
 
+    template <class MATRIX, class VECTOR>
+    inline void
+    SystemSimple<MATRIX,VECTOR>::initialize(const ConstraintMatrix &c)
+    {
+      MatrixSimple<MATRIX>::initialize(c);
+      ResidualSimple<VECTOR>::initialize(c);
+    }
 
+    
     template <class MATRIX, class VECTOR>
     template <class DOFINFO>
     inline void
diff --git a/deal.II/include/deal.II/multigrid/sparse_matrix_collection.h b/deal.II/include/deal.II/multigrid/sparse_matrix_collection.h
new file mode 100644 (file)
index 0000000..a7dd038
--- /dev/null
@@ -0,0 +1,124 @@
+// ---------------------------------------------------------------------
+// $Id: mg_matrix.h 30036 2013-07-18 16:55:32Z maier $
+//
+// Copyright (C) 2003 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#ifndef __deal2__mg_sparse_matrix_collection_h
+#define __deal2__mg_sparse_matrix_collection_h
+
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/pointer_matrix.h>
+#include <deal.II/lac/sparse_matrix.h>
+#include <deal.II/lac/compressed_sparsity_pattern.h>
+#include <deal.II/multigrid/mg_base.h>
+#include <deal.II/multigrid/mg_tools.h>
+#include <deal.II/base/mg_level_object.h>
+#include <deal.II/base/std_cxx1x/shared_ptr.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace mg
+{
+/**
+ * Handler and storage for all five SparseMatrix object involved in
+ * using multigrid with local refinement.
+ *
+ * @author Baerbel Janssen, Guido Kanschat
+ * @date 2013
+ */
+  template <typename number>
+  class SparseMatrixCollection : public Subscriptor
+  {
+    public:
+      void resize(const unsigned int minlevel, const unsigned  int maxlevel);
+      
+      template <class DH>
+      void reinit(const DH& dof_handler);
+
+      void set_zero();
+      
+      MGLevelObject<SparsityPattern> sparsity;
+      MGLevelObject<SparsityPattern> sparsity_edge;
+      
+      MGLevelObject<SparseMatrix<number> > matrix;
+      MGLevelObject<SparseMatrix<number> > matrix_down;
+      MGLevelObject<SparseMatrix<number> > matrix_up;
+      MGLevelObject<SparseMatrix<number> > matrix_in;
+      MGLevelObject<SparseMatrix<number> > matrix_out;
+  };
+
+
+  template <typename number>
+  void
+  SparseMatrixCollection<number>::resize(const unsigned int minlevel, const unsigned  int maxlevel)
+  {
+    matrix.resize(minlevel, maxlevel);
+    matrix.clear();
+    matrix_up.resize(minlevel+1, maxlevel);
+    matrix_up.clear();
+    matrix_down.resize(minlevel+1, maxlevel);
+    matrix_down.clear();
+    matrix_in.resize(minlevel, maxlevel);
+    matrix_in.clear();
+    matrix_out.resize(minlevel, maxlevel);
+    matrix_out.clear();
+    sparsity.resize(minlevel, maxlevel);
+    sparsity_edge.resize(minlevel, maxlevel);
+  }
+
+
+  template <typename number>
+  template <class DH>
+  void
+  SparseMatrixCollection<number>::reinit(const DH& dof_handler)
+  {
+    AssertIndexRange(sparsity.max_level(), dof_handler.get_tria().n_levels());
+    
+    for (unsigned int level=sparsity.min_level();
+        level<=sparsity.max_level();++level)
+      {
+       CompressedSparsityPattern c_sparsity(dof_handler.n_dofs(level));      
+       MGTools::make_flux_sparsity_pattern(dof_handler, c_sparsity, level);
+       sparsity[level].copy_from(c_sparsity);
+       matrix[level].reinit(sparsity[level]);
+       matrix_in[level].reinit(sparsity[level]);
+       matrix_out[level].reinit(sparsity[level]);
+       if (level>0)
+         {
+           CompressedSparsityPattern ci_sparsity;
+           ci_sparsity.reinit(dof_handler.n_dofs(level-1), dof_handler.n_dofs(level));
+           MGTools::make_flux_sparsity_pattern_edge(dof_handler, ci_sparsity, level);
+           sparsity_edge[level].copy_from(ci_sparsity);
+           matrix_up[level].reinit(sparsity_edge[level]);
+           matrix_down[level].reinit(sparsity_edge[level]);
+         }
+      }
+  }
+
+  template <typename number>
+  void
+  SparseMatrixCollection<number>::set_zero()
+  {
+    matrix = 0.;
+    matrix_in = 0.;
+    matrix_out = 0.;
+    matrix_up = 0.;
+    matrix_down = 0.;
+  }
+  
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
index 26cf9b1a5300e95ffdc3c6db59e3b442657016bb..7dfe9c9bd4fce6f65d093789c87896480f7778ec 100644 (file)
 
 
 #include <deal.II/base/config.h>
-#include <deal.II/base/smartpointer.h>
-#include <deal.II/base/data_out_base.h>
-#include <deal.II/dofs/dof_handler.h>
-#include <deal.II/grid/tria.h>
-#include <deal.II/fe/mapping.h>
-#include <deal.II/hp/q_collection.h>
-#include <deal.II/hp/fe_collection.h>
-#include <deal.II/hp/mapping_collection.h>
-#include <deal.II/hp/fe_values.h>
-#include <deal.II/numerics/data_postprocessor.h>
-#include <deal.II/numerics/data_component_interpretation.h>
+#include <deal.II/numerics/data_out_dof_data.h>
 
 #include <deal.II/base/std_cxx1x/shared_ptr.h>
 
@@ -42,214 +32,6 @@ namespace internal
 {
   namespace DataOut
   {
-    /**
-     * For each vector that has been added through the add_data_vector()
-     * functions, we need to keep track of a pointer to it, and allow data
-     * extraction from it when we generate patches. Unfortunately, we need to
-     * do this for a number of different vector types. Fortunately, they all
-     * have the same interface. So the way we go is to have a base class that
-     * provides the functions to access the vector's information, and to have
-     * a derived template class that can be instantiated for each vector
-     * type. Since the vectors all have the same interface, this is no big
-     * problem, as they can all use the same general templatized code.
-     *
-     * @author Wolfgang Bangerth, 2004
-     */
-    template <class DH>
-    class DataEntryBase
-    {
-    public:
-      /**
-       * Constructor. Give a list of names for the individual components of
-       * the vector and their interpretation as scalar or vector data. This
-       * constructor assumes that no postprocessor is going to be used.
-       */
-      DataEntryBase (const DH                       *dofs,
-                     const std::vector<std::string> &names,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
-
-      /**
-       * Constructor when a data postprocessor is going to be used. In that
-       * case, the names and vector declarations are going to be acquired from
-       * the postprocessor.
-       */
-      DataEntryBase (const DH                       *dofs,
-                     const DataPostprocessor<DH::space_dimension> *data_postprocessor);
-
-      /**
-       * Destructor made virtual.
-       */
-      virtual ~DataEntryBase ();
-
-      /**
-       * Assuming that the stored vector is a cell vector, extract the given
-       * element from it.
-       */
-      virtual
-      double
-      get_cell_data_value (const unsigned int cell_number) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the values on the present cell
-       * from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<double>             &patch_values) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the values on the present cell
-       * from the vector we actually store. This function does the same as the
-       * one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<dealii::Vector<double> >    &patch_values_system) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the gradients on the present
-       * cell from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                              std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the gradients on the present
-       * cell from the vector we actually store. This function does the same
-       * as the one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                              std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the second derivatives on the
-       * present cell from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                             std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const = 0;
-
-      /**
-       * Given a FEValuesBase object, extract the second derivatives on the
-       * present cell from the vector we actually store. This function does
-       * the same as the one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                             std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const = 0;
-
-      /**
-       * Clear all references to the vectors.
-       */
-      virtual void clear () = 0;
-
-      /**
-       * Determine an estimate for the memory consumption (in bytes) of this
-       * object.
-       */
-      virtual std::size_t memory_consumption () const = 0;
-
-      /**
-       * Pointer to the DoFHandler object that the vector is based on.
-       */
-      SmartPointer<const DH> dof_handler;
-
-      /**
-       * Names of the components of this data vector.
-       */
-      const std::vector<std::string> names;
-
-      /**
-       * A vector that for each of the n_output_variables variables of the
-       * current data set indicates whether they are scalar fields, parts of a
-       * vector-field, or any of the other supported kinds of data.
-       */
-      const std::vector<DataComponentInterpretation::DataComponentInterpretation>
-      data_component_interpretation;
-
-      /**
-       * Pointer to a DataPostprocessing object which shall be applied to this
-       * data vector.
-       */
-      SmartPointer<const dealii::DataPostprocessor<DH::space_dimension> > postprocessor;
-
-      /**
-       * Number of output variables this dataset provides (either number of
-       * components in vector valued function / data vector or number of
-       * computed quantities, if DataPostprocessor is applied). This variable
-       * is determined via and thus equivalent to <tt>names.size()</tt>.
-       */
-      unsigned int n_output_variables;
-    };
-
-
-    /**
-     * A data structure that holds all data needed in one thread when building
-     * patches in parallel. These data structures are created globally rather
-     * than on each cell to avoid allocation of memory in the threads. This is
-     * a base class for the AdditionalData kind of data structure discussed in
-     * the documentation of the WorkStream class.
-     *
-     * The <code>cell_to_patch_index_map</code> is an array that stores for
-     * index <tt>[i][j]</tt> the number of the patch that associated with the
-     * cell with index @p j on level @p i. This information is set up prior to
-     * generation of the patches, and is needed to generate neighborship
-     * information.
-     *
-     * This structure is used by several of the DataOut* classes, which
-     * derived their own ParallelData classes from it for additional fields.
-     */
-    template <int dim, int spacedim>
-    struct ParallelDataBase
-    {
-      ParallelDataBase (const unsigned int n_datasets,
-                        const unsigned int n_subdivisions,
-                        const std::vector<unsigned int> &n_postprocessor_outputs,
-                        const Mapping<dim,spacedim> &mapping,
-                        const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
-                        const UpdateFlags update_flags,
-                        const bool        use_face_values);
-
-      ParallelDataBase (const ParallelDataBase &data);
-
-      template <typename DH>
-      void reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
-                                const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
-                                const unsigned int face = numbers::invalid_unsigned_int);
-
-      const FEValuesBase<dim,spacedim> &
-      get_present_fe_values(const unsigned int dataset) const;
-
-      void resize_system_vectors(const unsigned int n_components);
-
-      const unsigned int n_datasets;
-      const unsigned int n_subdivisions;
-
-      std::vector<double>                                patch_values;
-      std::vector<dealii::Vector<double> >               patch_values_system;
-      std::vector<Tensor<1,spacedim> >                   patch_gradients;
-      std::vector<std::vector<Tensor<1,spacedim> > >     patch_gradients_system;
-      std::vector<Tensor<2,spacedim> >                   patch_hessians;
-      std::vector<std::vector<Tensor<2,spacedim> > >     patch_hessians_system;
-      std::vector<std::vector<dealii::Vector<double> > > postprocessed_values;
-
-      const dealii::hp::MappingCollection<dim,spacedim> mapping_collection;
-      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > finite_elements;
-      const UpdateFlags update_flags;
-
-      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEValues<dim,spacedim> > > x_fe_values;
-      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEFaceValues<dim,spacedim> > > x_fe_face_values;
-    };
-
-
     /**
      * A derived class for use in the DataOut class. This is a class for the
      * AdditionalData kind of data structure discussed in the documentation of
@@ -274,591 +56,6 @@ namespace internal
 }
 
 
-//TODO: Most of the documentation of DataOut_DoFData applies to DataOut.
-
-/**
- * This is an abstract class which provides the functionality to generate
- * patches for output by base classes from data vectors on a grid. It allows
- * to store one or more pointers to a DoFHandler and attached node and cell
- * data denoting functions on the grid which shall later be written in any of
- * the implemented data formats.
- *
- *
- * <h3>User visible interface</h3>
- *
- * The user visible interface of this class allows the user to specify data in
- * two different ways. One is to make a DoFHandler object known to this class
- * and to add data vectors that all correspond to this DoFHandler or the grid
- * cells which will later be written to a file in some format. The second
- * approach is to pass a DoFHandler object along with the vector. This allows
- * setting data from different DoFHandlers in a neat way (of course, they both
- * need to be based on the same triangulation). Instead of pondering about the
- * different functions, an example for the first kind is probably the best
- * explanation:
- * @code
- *   ...
- *   ...   // compute solution, which contains nodal values
- *   ...
- *   ...   // compute error_estimator, which contains one value per cell
- *
- *   std::vector<std::string> solution_names;
- *   solution_names.push_back ("x-displacement");
- *   solution_names.push_back ("y-displacement");
- *
- *   DataOut<dim> data_out;
- *   data_out.attach_dof_handler (dof_handler);
- *   data_out.add_data_vector (solution, solution_names);
- *   data_out.add_data_vector (error_estimator, "estimated_error");
- *
- *   data_out.build_patches ();
- *
- *   ofstream output_file ("output");
- *   data_out.write_xxx (output_file);
- *
- *   data_out.clear();
- * @endcode
- *
- * attach_dof_handler() tells this class that all future operations
- * are to take place with the DoFHandler object and the triangulation
- * it lives on. We then add the solution vector and the error
- * estimator; note that they have different dimensions, because the
- * solution is a nodal vector, here consisting of two components
- * ("x-displacement" and "y-displacement") while the error estimator
- * probably is a vector holding cell data. When attaching a data
- * vector, you have to give a name to each component of the vector,
- * which is done through an object of type <tt>vector<string></tt> as
- * second argument; if only one component is in the vector, for
- * example if we are adding cell data as in the second case, or if the
- * finite element used by the DoFHandler has only one component, then
- * you can use the second add_data_vector() function which takes a @p
- * string instead of the <tt>vector<string></tt>.
- *
- * The add_data_vector() functions have additional arguments (with default
- * values) that can be used to specify certain transformations. In particular,
- * it allows to attach DataPostprocessor arguments to compute derived
- * information from a data vector at each point at which the field will
- * be evaluated so that it can be written to a file (for example, the
- * Mach number in hypersonic flow can be computed from density and velocities;
- * step-29 also shows an example); another piece of information
- * specified through arguments with default values is how certain output
- * components should be interpreted, i.e. whether each component of the data
- * is logically an independent scalar field, or whether some of them together
- * form logically a vector-field (see the
- * DataComponentInterpretation::DataComponentInterpretation enum, and the @ref
- * step_22 "step-22" tutorial program).
- *
- * It should be noted that this class does not copy the vector given to it through
- * the add_data_vector() functions, for memory consumption reasons. It only
- * stores a reference to it, so it is in your responsibility to make sure that
- * the data vectors exist long enough.
- *
- * After adding all data vectors, you need to call a function which generates
- * the patches for output from the stored data. Derived classes name this
- * function build_patches(). Finally, you write() the data in one format or other,
- * to a file.
- *
- * Please note that in the example above, an object of type DataOut was
- * used, i.e. an object of a derived class. This is necessary since this
- * class does not provide means to actually generate the patches, only aids to
- * store and access data.
- *
- * Note that the base class of this class, DataOutInterface offers
- * several functions to ease programming with run-time determinable
- * output formats (i.e. you need not use a fixed format by calling
- * DataOutInterface::write_xxx in the above example, but you can
- * select it by a run-time parameter without having to write the
- * <tt>if () ... else ...</tt> clauses yourself), and also functions
- * and classes offering ways to control the appearance of the output
- * by setting flags for each output format.
- *
- *
- * <h3>Information for derived classes</h3>
- *
- * What is actually missing this class is a way to produce the patches
- * for output itself, from the stored data and degree of freedom
- * information.  Since this task is often application dependent it is
- * left to derived classes. For example, in many applications, it
- * might be wanted to limit the depth of output to a certain number of
- * refinement levels and write data from finer cells only in a way
- * interpolated to coarser cells, to reduce the amount of
- * output. Also, it might be wanted to use different numbers of
- * subdivisions on different cells when forming a patch, for example
- * to accomplish for different polynomial degrees of the trial space
- * on different cells. Also, the output need not necessarily consist
- * of a patch for each cell, but might be made up of patches for
- * faces, of other things. Take a look at derived classes to what is
- * possible in this respect.
- *
- * For this reason, it is left to a derived class to provide a
- * function, named usually build_patches() or the like, which fills
- * the #patches array of this class.
- *
- * Regarding the templates of this class, it needs three values: first
- * the space dimension in which the triangulation and the DoF handler
- * operate, second the dimension of the objects which the patches
- * represent.  Although in most cases they are equal, there are also
- * classes for which this does not hold, for example if one outputs
- * the result of a computation exploiting rotational symmetry in the
- * original domain (in which the space dimension of the output would
- * be one higher than that of the DoF handler, see the
- * DataOut_Rotation() class), or one might conceive that one could
- * write a class that only outputs the solution on a cut through the
- * domain, in which case the space dimension of the output is less
- * than that of the DoF handler. The last template argument denotes
- * the dimension of the space into which the patches are embedded;
- * usually, this dimension is the same as the dimensio of the patches
- * themselves (which is also the default value of the template
- * parameter), but there might be cases where this is not so. For
- * example, in the DataOut_Faces() class, patches are generated
- * from faces of the triangulation. Thus, the dimension of the patch
- * is one less than the dimension of the embedding space, which is, in
- * this case, equal to the dimension of the triangulation and DoF
- * handler. However, for the cut through the domain mentioned above,
- * if the cut is a straight one, then the cut can be embedded into a
- * space of one dimension lower than the dimension of the
- * triangulation, so that the last template parameter has the same
- * value as the second one.
- *
- * @ingroup output
- * @author Wolfgang Bangerth, 1999
- */
-template <class DH, int patch_dim, int patch_space_dim=patch_dim>
-class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
-{
-public:
-
-  /**
-   * Typedef to the iterator type of the dof handler class under
-   * consideration.
-   */
-  typedef typename Triangulation<DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
-  typedef typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
-
-public:
-
-  /**
-   * Type describing what the vector given to add_data_vector() is: a vector
-   * that has one entry per degree of freedom in a DoFHandler object (such as
-   * solution vectors), or one entry per cell in the triangulation underlying
-   * the DoFHandler object (such as error per cell data). The value
-   * #type_automatic tells add_data_vector() to find out itself (see the
-   * documentation of add_data_vector() for the method used).
-   */
-  enum DataVectorType
-  {
-    /**
-     * Data vector entries are associated to degrees of freedom
-     */
-    type_dof_data,
-
-    /**
-     * Data vector entries are one per grid cell
-     */
-    type_cell_data,
-
-    /**
-     * Find out automatically
-     */
-    type_automatic
-  };
-
-  /**
-   * Constructor
-   */
-  DataOut_DoFData ();
-
-  /**
-   * Destructor.
-   */
-  virtual ~DataOut_DoFData ();
-
-  /**
-   * Designate a dof handler to be used to extract geometry data and the
-   * mapping between nodes and node values. This call is not necessary if all
-   * added data vectors are supplemented with a DoFHandler argument.
-   *
-   * This call is optional: If you add data vectors with specified DoFHandler
-   * object, then that contains all information needed to generate the output.
-   */
-  void attach_dof_handler (const DH &);
-
-  /**
-   * Designate a triangulation to be used to extract geometry data and the
-   * mapping between nodes and node values.
-   *
-   * This call is optional: If you add data vectors with specified DoFHandler
-   * object, then that contains all information needed to generate the
-   * output. This call is useful when you only output cell vectors and no
-   * DoFHandler at all, in which case it provides the geometry.
-   */
-  void attach_triangulation (const Triangulation<DH::dimension,
-                             DH::space_dimension> &);
-
-  /**
-   * Add a data vector together with its name.
-   *
-   * A pointer to the vector is stored, so you have to make sure the vector
-   * exists at that address at least as long as you call the <tt>write_*</tt>
-   * functions.
-   *
-   * It is assumed that the vector has the same number of components as there
-   * are degrees of freedom in the dof handler, in which case it is assumed to
-   * be a vector storing nodal data; or the size may be the number of active
-   * cells on the present grid, in which case it is assumed to be a cell data
-   * vector. As the number of degrees of freedom and of cells is usually not
-   * equal, the function can determine itself which type of vector it is
-   * given. However, there are corner cases where this automatic determination
-   * does not work.  One example is if you compute with piecewise constant
-   * elements and have a scalar solution, then there are as many cells as
-   * there are degrees of freedom (though they may be numbered
-   * differently). Another possibility is if you have a 1d mesh embedded in 2d
-   * space and the mesh consists of a closed curve of cells; in this case,
-   * there are as many nodes as there are cells, and when using a Q1 element
-   * you will have as many degrees of freedom as there are cells.  In these
-   * cases, you can change the last argument of the function from its default
-   * value #type_automatic to either #type_dof_data or #type_cell_data,
-   * depending on what the vector represents. Apart from such corner cases,
-   * you can leave the argument at its default value and let the function
-   * determine the type of the vector itself.
-   *
-   * If it is a vector holding DoF data, the names given shall be one for each
-   * component of the underlying finite element.  If it is a finite element
-   * composed of only one subelement, then there is another function following
-   * which takes a single name instead of a vector of names.
-   *
-   * The data_component_interpretation argument contains information about how
-   * the individual components of output files that consist of more than one
-   * data set are to be interpreted.
-   *
-   * For example, if one has a finite element for the Stokes equations in 2d,
-   * representing components (u,v,p), one would like to indicate that the
-   * first two, u and v, represent a logical vector so that later on when we
-   * generate graphical output we can hand them off to a visualization program
-   * that will automatically know to render them as a vector field, rather
-   * than as two separate and independent scalar fields.
-   *
-   * The default value of this argument (i.e. an empty vector) corresponds is
-   * equivalent to a vector of values
-   * DataComponentInterpretation::component_is_scalar, indicating that all
-   * output components are independent scalar fields. However, if the given
-   * data vector represents logical vectors, you may pass a vector that
-   * contains values
-   * DataComponentInterpretation::component_is_part_of_vector. In the example
-   * above, one would pass in a vector with components
-   * (DataComponentInterpretation::component_is_part_of_vector,
-   * DataComponentInterpretation::component_is_part_of_vector,
-   * DataComponentInterpretation::component_is_scalar) for (u,v,p).
-   *
-   * The names of a data vector shall only contain characters which are
-   * letters, underscore and a few other ones. Refer to the
-   * ExcInvalidCharacter exception declared in this class to see which
-   * characters are valid and which are not.
-   *
-   * @note The actual type for the vector argument may be any vector type from
-   * which FEValues can extract values on a cell using the
-   * FEValuesBase::get_function_values() function. In particular, this
-   * includes all of the usual vector types, but also IndexSet (see step-41
-   * for a use of this).
-   */
-  template <class VECTOR>
-  void add_data_vector (const VECTOR                   &data,
-                        const std::vector<std::string> &names,
-                        const DataVectorType            type = type_automatic,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
-                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
-
-  /**
-   * This function is an abbreviation to the above one (see there for a
-   * discussion of the various arguments), intended for use with finite
-   * elements that are not composed of subelements. In this case, only one
-   * name per data vector needs to be given, which is what this function
-   * takes. It simply relays its arguments after a conversion of the @p name
-   * to a vector of strings, to the other add_data_vector() function above.
-   *
-   * If @p data is a vector with multiple components this function will
-   * generate distinct names for all components by appending an underscore and
-   * the number of each component to @p name
-   *
-   * The actual type for the template argument may be any vector type from
-   * which FEValues can extract values on a cell using the
-   * FEValuesBase::get_function_values() function.
-   */
-  template <class VECTOR>
-  void add_data_vector (const VECTOR         &data,
-                        const std::string    &name,
-                        const DataVectorType  type = type_automatic,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
-                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
-
-  /**
-   * This function is an extension of the above one (see there for a
-   * discussion of the arguments except the first one) and allows to set a
-   * vector with its own DoFHandler object. This DoFHandler needs to be
-   * compatible with the other DoFHandler objects assigned with calls to @p
-   * add_data_vector or @p attach_dof_handler, in the sense that the
-   * DoFHandler objects need to be based on the same triangulation. This
-   * function allows you to export data from multiple DoFHandlers that
-   * describe different solution components.
-   *
-   * Since this function takes a DoFHandler object and hence naturally
-   * represents dof data, the data vector type argument present in the other
-   * methods above is skipped.
-   */
-  template <class VECTOR>
-  void add_data_vector (const DH                       &dof_handler,
-                        const VECTOR                   &data,
-                        const std::vector<std::string> &names,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
-                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
-
-
-  /**
-   * This function is an abbreviation of the function above with only a scalar
-   * @p dof_handler given and a single data name.
-   */
-  template <class VECTOR>
-  void add_data_vector (const DH                       &dof_handler,
-                        const VECTOR                   &data,
-                        const std::string              &name,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
-                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
-
-  /**
-   * This function is an alternative to the above ones, allowing the output of
-   * derived quantities instead of the given data. This converison has to be
-   * done in a class derived from DataPostprocessor.
-   *
-   * The names for these derived quantities are provided by the @p
-   * data_postprocessor argument. Likewise, the data_component_interpretation
-   * argument of the other add_data_vector() functions is provided by the
-   * data_postprocessor argument. As only data of type @p type_dof_data can be
-   * transformed, this type is also known implicitly and does not have to be
-   * given.
-   *
-   * @note The actual type for the vector argument may be any vector type from
-   * which FEValues can extract values on a cell using the
-   * FEValuesBase::get_function_values() function. In particular, this
-   * includes all of the usual vector types, but also IndexSet (see step-41
-   * for a use of this).
-   */
-  template <class VECTOR>
-  void add_data_vector (const VECTOR                           &data,
-                        const DataPostprocessor<DH::space_dimension> &data_postprocessor);
-
-  /**
-   * Same function as above, but with a DoFHandler object that does not need
-   * to coincide with the DoFHandler initially set. Note that the
-   * postprocessor can only read data from the given DoFHandler and solution
-   * vector, not other solution vectors or DoFHandlers.
-   */
-  template <class VECTOR>
-  void add_data_vector (const DH                               &dof_handler,
-                        const VECTOR                           &data,
-                        const DataPostprocessor<DH::space_dimension> &data_postprocessor);
-
-  /**
-   * Release the pointers to the data vectors. This allows output of a new set
-   * of vectors without supplying the DoF handler again. Therefore, the
-   * DataOut object can be used in an algebraic context. Note that besides the
-   * data vectors also the patches already computed are deleted.
-   */
-  void clear_data_vectors ();
-
-  /**
-   * Release pointers to all input data elements, i.e. pointers to data
-   * vectors and to the DoF handler object. This function may be useful when
-   * you have called the @p build_patches function of derived class, since
-   * then the patches are built and the input data is no more needed, nor is
-   * there a need to reference it. You can then output the patches detached
-   * from the main thread and need not make sure anymore that the DoF handler
-   * object and vectors must not be deleted before the output thread is
-   * finished.
-   */
-  void clear_input_data_references ();
-
-  /**
-   * This function can be used to merge the patches that were created using
-   * the @p build_patches function of the object given as argument into the
-   * list of patches created by this object. This is sometimes handy if one
-   * has, for example, a domain decomposition algorithm where each block is
-   * represented by a DoFHandler of its own, but one wants to output the
-   * solution on all the blocks at the same time.
-   *
-   * For this to work, the given argument and this object need to have the
-   * same number of output vectors, and they need to use the same number of
-   * subdivisions per patch. The output will probably look rather funny if
-   * patches in both objects overlap in space.
-   *
-   * If you call build_patches() for this object after merging in patches, the
-   * previous state is overwritten, and the merged-in patches are lost.
-   *
-   * The second parameter allows to shift each node of the patches in the
-   * object passed in in the first parameter by a certain amount. This is
-   * sometimes useful to generate "exploded" views of a collection of blocks.
-   *
-   * This function will fail if either this or the other object did not yet
-   * set up any patches.
-   */
-  template <class DH2>
-  void merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
-                      const Point<patch_space_dim> &shift = Point<patch_space_dim>());
-
-  /**
-   * Release the pointers to the data vectors and the DoF handler. You have to
-   * set all data entries again using the add_data_vector() function. The
-   * pointer to the dof handler is cleared as well, along with all other
-   * data. In effect, this function resets everything to a virgin state.
-   */
-  virtual void clear ();
-
-  /**
-   * Determine an estimate for the memory consumption (in bytes) of this
-   * object.
-   */
-  std::size_t memory_consumption () const;
-
-  /**
-   * Exception
-   */
-  DeclException0 (ExcNoTriangulationSelected);
-
-  /**
-   * Exception
-   */
-  DeclException0 (ExcNoDoFHandlerSelected);
-
-  /**
-   * Exception
-   */
-  DeclException0 (ExcDataPostprocessingIsNotPossibleForCellData);
-
-  /**
-   * Exception
-   */
-  DeclException3 (ExcInvalidVectorSize,
-                  int, int, int,
-                  << "The vector has size " << arg1
-                  << " but the DoFHandler objects says there are " << arg2
-                  << " degrees of freedom and there are " << arg3
-                  << " active cells.");
-  /**
-   * Exception
-   */
-  DeclException2 (ExcInvalidCharacter,
-                  std::string, size_t,
-                  << "Please use only the characters [a-zA-Z0-9_<>()] for" << std::endl
-                  << "description strings since some graphics formats will only accept these."
-                  << std::endl
-                  << "The string you gave was <" << arg1
-                  << ">, the invalid character is <" << arg1[arg2]
-                  << ">." << std::endl);
-  /**
-   * Exception
-   */
-  DeclException0 (ExcOldDataStillPresent);
-  /**
-   * Exception
-   */
-  DeclException2 (ExcInvalidNumberOfNames,
-                  int, int,
-                  << "You have to give one name per component in your "
-                  << "data vector. The number you gave was " << arg1
-                  << ", but the number of components is " << arg2);
-  /**
-   * Exception
-   */
-  DeclException0 (ExcNoPatches);
-  /**
-   * Exception
-   */
-  DeclException0 (ExcIncompatibleDatasetNames);
-  /**
-   * Exception
-   */
-  DeclException0 (ExcIncompatiblePatchLists);
-
-  DeclException2 (ExcInvalidVectorDeclaration,
-                  int, std::string,
-                  << "When declaring that a number of components in a data\n"
-                  << "set to be output logically form a vector instead of\n"
-                  << "simply a set of scalar fields, you need to specify\n"
-                  << "this for all relevant components. Furthermore,\n"
-                  << "vectors must always consist of exactly <dim>\n"
-                  << "components. However, the vector component at\n"
-                  << "position " << arg1 << " with name <" << arg2
-                  << "> does not satisfy these conditions.");
-
-protected:
-  /**
-   * Abbreviate the somewhat lengthy name for the Patch class.
-   */
-  typedef dealii::DataOutBase::Patch<patch_dim,patch_space_dim> Patch;
-
-  /**
-   * Pointer to the triangulation object.
-   */
-  SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> > triangulation;
-
-  /**
-   * Pointer to the optional handler object.
-   */
-  SmartPointer<const DH> dofs;
-
-  /**
-   * List of data elements with vectors of values for each degree of freedom.
-   */
-  std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  dof_data;
-
-  /**
-   * List of data elements with vectors of values for each cell.
-   */
-  std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  cell_data;
-
-  /**
-   * This is a list of patches that is created each time build_patches() is
-   * called. These patches are used in the output routines of the base
-   * classes.
-   */
-  std::vector<Patch> patches;
-
-  /**
-   * Function by which the base class's functions get to know what patches
-   * they shall write to a file.
-   */
-  virtual
-  const std::vector<Patch> &get_patches () const;
-
-  /**
-   * Virtual function through which the names of data sets are obtained by the
-   * output functions of the base class.
-   */
-  virtual
-  std::vector<std::string> get_dataset_names () const;
-
-  /**
-   * Extracts the finite elements stored in the dof_data object, including a
-   * dummy object of FE_DGQ<dim>(0) in case only the triangulation is used.
-   */
-  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
-  get_finite_elements() const;
-
-  /**
-   * Overload of the respective DataOutInterface::get_vector_data_ranges()
-   * function. See there for a more extensive documentation.
-   */
-  virtual
-  std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
-  get_vector_data_ranges () const;
-
-  /**
-   * Make all template siblings friends. Needed for the merge_patches()
-   * function.
-   */
-  template <class, int, int>
-  friend class DataOut_DoFData;
-};
-
-
 
 /**
  * This class is the main class to provide output of data described by finite
@@ -1061,83 +258,6 @@ private:
 
 
 
-// -------------------- template and inline functions ------------------------
-
-
-template <class DH, int patch_dim, int patch_space_dim>
-template <class DH2>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
-               const Point<patch_space_dim> &shift)
-{
-  const std::vector<Patch> source_patches = source.get_patches ();
-  Assert (patches.size () != 0,        ExcNoPatches ());
-  Assert (source_patches.size () != 0, ExcNoPatches ());
-  // check equality of component
-  // names
-  Assert (get_dataset_names() == source.get_dataset_names(),
-          ExcIncompatibleDatasetNames());
-  // make sure patches are compatible. we'll
-  // assume that if the first respective
-  // patches are ok that all the other ones
-  // are ok as well
-  Assert (patches[0].n_subdivisions == source_patches[0].n_subdivisions,
-          ExcIncompatiblePatchLists());
-  Assert (patches[0].data.n_rows() == source_patches[0].data.n_rows(),
-          ExcIncompatiblePatchLists());
-  Assert (patches[0].data.n_cols() == source_patches[0].data.n_cols(),
-          ExcIncompatiblePatchLists());
-
-  // check equality of the vector data
-  // specifications
-  Assert (get_vector_data_ranges().size() ==
-          source.get_vector_data_ranges().size(),
-          ExcMessage ("Both sources need to declare the same components "
-                      "as vectors."));
-  for (unsigned int i=0; i<get_vector_data_ranges().size(); ++i)
-    {
-      Assert (std_cxx1x::get<0>(get_vector_data_ranges()[i]) ==
-              std_cxx1x::get<0>(source.get_vector_data_ranges()[i]),
-              ExcMessage ("Both sources need to declare the same components "
-                          "as vectors."));
-      Assert (std_cxx1x::get<1>(get_vector_data_ranges()[i]) ==
-              std_cxx1x::get<1>(source.get_vector_data_ranges()[i]),
-              ExcMessage ("Both sources need to declare the same components "
-                          "as vectors."));
-      Assert (std_cxx1x::get<2>(get_vector_data_ranges()[i]) ==
-              std_cxx1x::get<2>(source.get_vector_data_ranges()[i]),
-              ExcMessage ("Both sources need to declare the same components "
-                          "as vectors."));
-    }
-
-  // merge patches. store old number
-  // of elements, since we need to
-  // adjust patch numbers, etc
-  // afterwards
-  const unsigned int old_n_patches = patches.size();
-  patches.insert (patches.end(),
-                  source_patches.begin(),
-                  source_patches.end());
-
-  // perform shift, if so desired
-  if (shift != Point<patch_space_dim>())
-    for (unsigned int i=old_n_patches; i<patches.size(); ++i)
-      for (unsigned int v=0; v<GeometryInfo<patch_dim>::vertices_per_cell; ++v)
-        patches[i].vertices[v] += shift;
-
-  // adjust patch numbers
-  for (unsigned int i=old_n_patches; i<patches.size(); ++i)
-    patches[i].patch_index += old_n_patches;
-
-  // adjust patch neighbors
-  for (unsigned int i=old_n_patches; i<patches.size(); ++i)
-    for (unsigned int n=0; n<GeometryInfo<patch_dim>::faces_per_cell; ++n)
-      if (patches[i].neighbors[n] != Patch::no_neighbor)
-        patches[i].neighbors[n] += old_n_patches;
-}
-
-
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
diff --git a/deal.II/include/deal.II/numerics/data_out_dof_data.h b/deal.II/include/deal.II/numerics/data_out_dof_data.h
new file mode 100644 (file)
index 0000000..fdc24db
--- /dev/null
@@ -0,0 +1,920 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1999 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#ifndef __deal2__data_out_dof_data_h
+#define __deal2__data_out_dof_data_h
+
+
+
+#include <deal.II/base/config.h>
+#include <deal.II/base/smartpointer.h>
+#include <deal.II/base/data_out_base.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/fe/mapping.h>
+#include <deal.II/hp/q_collection.h>
+#include <deal.II/hp/fe_collection.h>
+#include <deal.II/hp/mapping_collection.h>
+#include <deal.II/hp/fe_values.h>
+#include <deal.II/numerics/data_postprocessor.h>
+#include <deal.II/numerics/data_component_interpretation.h>
+
+#include <deal.II/base/std_cxx1x/shared_ptr.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+template <int, int> class FEValuesBase;
+
+namespace internal
+{
+  namespace DataOut
+  {
+    /**
+     * For each vector that has been added through the add_data_vector()
+     * functions, we need to keep track of a pointer to it, and allow data
+     * extraction from it when we generate patches. Unfortunately, we need to
+     * do this for a number of different vector types. Fortunately, they all
+     * have the same interface. So the way we go is to have a base class that
+     * provides the functions to access the vector's information, and to have
+     * a derived template class that can be instantiated for each vector
+     * type. Since the vectors all have the same interface, this is no big
+     * problem, as they can all use the same general templatized code.
+     *
+     * @author Wolfgang Bangerth, 2004
+     */
+    template <class DH>
+    class DataEntryBase
+    {
+    public:
+      /**
+       * Constructor. Give a list of names for the individual components of
+       * the vector and their interpretation as scalar or vector data. This
+       * constructor assumes that no postprocessor is going to be used.
+       */
+      DataEntryBase (const DH                       *dofs,
+                     const std::vector<std::string> &names,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
+
+      /**
+       * Constructor when a data postprocessor is going to be used. In that
+       * case, the names and vector declarations are going to be acquired from
+       * the postprocessor.
+       */
+      DataEntryBase (const DH                       *dofs,
+                     const DataPostprocessor<DH::space_dimension> *data_postprocessor);
+
+      /**
+       * Destructor made virtual.
+       */
+      virtual ~DataEntryBase ();
+
+      /**
+       * Assuming that the stored vector is a cell vector, extract the given
+       * element from it.
+       */
+      virtual
+      double
+      get_cell_data_value (const unsigned int cell_number) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<double>             &patch_values) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store. This function does the same as the
+       * one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<dealii::Vector<double> >    &patch_values_system) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store. This function does the same
+       * as the one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                             std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const = 0;
+
+      /**
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store. This function does
+       * the same as the one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                             std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const = 0;
+
+      /**
+       * Clear all references to the vectors.
+       */
+      virtual void clear () = 0;
+
+      /**
+       * Determine an estimate for the memory consumption (in bytes) of this
+       * object.
+       */
+      virtual std::size_t memory_consumption () const = 0;
+
+      /**
+       * Pointer to the DoFHandler object that the vector is based on.
+       */
+      SmartPointer<const DH> dof_handler;
+
+      /**
+       * Names of the components of this data vector.
+       */
+      const std::vector<std::string> names;
+
+      /**
+       * A vector that for each of the n_output_variables variables of the
+       * current data set indicates whether they are scalar fields, parts of a
+       * vector-field, or any of the other supported kinds of data.
+       */
+      const std::vector<DataComponentInterpretation::DataComponentInterpretation>
+      data_component_interpretation;
+
+      /**
+       * Pointer to a DataPostprocessing object which shall be applied to this
+       * data vector.
+       */
+      SmartPointer<const dealii::DataPostprocessor<DH::space_dimension> > postprocessor;
+
+      /**
+       * Number of output variables this dataset provides (either number of
+       * components in vector valued function / data vector or number of
+       * computed quantities, if DataPostprocessor is applied). This variable
+       * is determined via and thus equivalent to <tt>names.size()</tt>.
+       */
+      unsigned int n_output_variables;
+    };
+
+
+    /**
+     * A data structure that holds all data needed in one thread when building
+     * patches in parallel. These data structures are created globally rather
+     * than on each cell to avoid allocation of memory in the threads. This is
+     * a base class for the AdditionalData kind of data structure discussed in
+     * the documentation of the WorkStream class.
+     *
+     * The <code>cell_to_patch_index_map</code> is an array that stores for
+     * index <tt>[i][j]</tt> the number of the patch that associated with the
+     * cell with index @p j on level @p i. This information is set up prior to
+     * generation of the patches, and is needed to generate neighborship
+     * information.
+     *
+     * This structure is used by several of the DataOut* classes, which
+     * derived their own ParallelData classes from it for additional fields.
+     */
+    template <int dim, int spacedim>
+    struct ParallelDataBase
+    {
+      ParallelDataBase (const unsigned int n_datasets,
+                        const unsigned int n_subdivisions,
+                        const std::vector<unsigned int> &n_postprocessor_outputs,
+                        const Mapping<dim,spacedim> &mapping,
+                        const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                        const UpdateFlags update_flags,
+                        const bool        use_face_values);
+
+      ParallelDataBase (const ParallelDataBase &data);
+
+      template <typename DH>
+      void reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
+                                const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
+                                const unsigned int face = numbers::invalid_unsigned_int);
+
+      const FEValuesBase<dim,spacedim> &
+      get_present_fe_values(const unsigned int dataset) const;
+
+      void resize_system_vectors(const unsigned int n_components);
+
+      const unsigned int n_datasets;
+      const unsigned int n_subdivisions;
+
+      std::vector<double>                                patch_values;
+      std::vector<dealii::Vector<double> >               patch_values_system;
+      std::vector<Tensor<1,spacedim> >                   patch_gradients;
+      std::vector<std::vector<Tensor<1,spacedim> > >     patch_gradients_system;
+      std::vector<Tensor<2,spacedim> >                   patch_hessians;
+      std::vector<std::vector<Tensor<2,spacedim> > >     patch_hessians_system;
+      std::vector<std::vector<dealii::Vector<double> > > postprocessed_values;
+
+      const dealii::hp::MappingCollection<dim,spacedim> mapping_collection;
+      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > finite_elements;
+      const UpdateFlags update_flags;
+
+      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEValues<dim,spacedim> > > x_fe_values;
+      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEFaceValues<dim,spacedim> > > x_fe_face_values;
+    };
+  }
+}
+
+
+//TODO: Most of the documentation of DataOut_DoFData applies to DataOut.
+
+/**
+ * This is an abstract class which provides the functionality to generate
+ * patches for output by base classes from data vectors on a grid. It allows
+ * to store one or more pointers to a DoFHandler and attached node and cell
+ * data denoting functions on the grid which shall later be written in any of
+ * the implemented data formats.
+ *
+ *
+ * <h3>User visible interface</h3>
+ *
+ * The user visible interface of this class allows the user to specify data in
+ * two different ways. One is to make a DoFHandler object known to this class
+ * and to add data vectors that all correspond to this DoFHandler or the grid
+ * cells which will later be written to a file in some format. The second
+ * approach is to pass a DoFHandler object along with the vector. This allows
+ * setting data from different DoFHandlers in a neat way (of course, they both
+ * need to be based on the same triangulation). Instead of pondering about the
+ * different functions, an example for the first kind is probably the best
+ * explanation:
+ * @code
+ *   ...
+ *   ...   // compute solution, which contains nodal values
+ *   ...
+ *   ...   // compute error_estimator, which contains one value per cell
+ *
+ *   std::vector<std::string> solution_names;
+ *   solution_names.push_back ("x-displacement");
+ *   solution_names.push_back ("y-displacement");
+ *
+ *   DataOut<dim> data_out;
+ *   data_out.attach_dof_handler (dof_handler);
+ *   data_out.add_data_vector (solution, solution_names);
+ *   data_out.add_data_vector (error_estimator, "estimated_error");
+ *
+ *   data_out.build_patches ();
+ *
+ *   ofstream output_file ("output");
+ *   data_out.write_xxx (output_file);
+ *
+ *   data_out.clear();
+ * @endcode
+ *
+ * attach_dof_handler() tells this class that all future operations
+ * are to take place with the DoFHandler object and the triangulation
+ * it lives on. We then add the solution vector and the error
+ * estimator; note that they have different dimensions, because the
+ * solution is a nodal vector, here consisting of two components
+ * ("x-displacement" and "y-displacement") while the error estimator
+ * probably is a vector holding cell data. When attaching a data
+ * vector, you have to give a name to each component of the vector,
+ * which is done through an object of type <tt>vector<string></tt> as
+ * second argument; if only one component is in the vector, for
+ * example if we are adding cell data as in the second case, or if the
+ * finite element used by the DoFHandler has only one component, then
+ * you can use the second add_data_vector() function which takes a @p
+ * string instead of the <tt>vector<string></tt>.
+ *
+ * The add_data_vector() functions have additional arguments (with default
+ * values) that can be used to specify certain transformations. In particular,
+ * it allows to attach DataPostprocessor arguments to compute derived
+ * information from a data vector at each point at which the field will
+ * be evaluated so that it can be written to a file (for example, the
+ * Mach number in hypersonic flow can be computed from density and velocities;
+ * step-29 also shows an example); another piece of information
+ * specified through arguments with default values is how certain output
+ * components should be interpreted, i.e. whether each component of the data
+ * is logically an independent scalar field, or whether some of them together
+ * form logically a vector-field (see the
+ * DataComponentInterpretation::DataComponentInterpretation enum, and the @ref
+ * step_22 "step-22" tutorial program).
+ *
+ * It should be noted that this class does not copy the vector given to it through
+ * the add_data_vector() functions, for memory consumption reasons. It only
+ * stores a reference to it, so it is in your responsibility to make sure that
+ * the data vectors exist long enough.
+ *
+ * After adding all data vectors, you need to call a function which generates
+ * the patches for output from the stored data. Derived classes name this
+ * function build_patches(). Finally, you write() the data in one format or other,
+ * to a file.
+ *
+ * Please note that in the example above, an object of type DataOut was
+ * used, i.e. an object of a derived class. This is necessary since this
+ * class does not provide means to actually generate the patches, only aids to
+ * store and access data.
+ *
+ * Note that the base class of this class, DataOutInterface offers
+ * several functions to ease programming with run-time determinable
+ * output formats (i.e. you need not use a fixed format by calling
+ * DataOutInterface::write_xxx in the above example, but you can
+ * select it by a run-time parameter without having to write the
+ * <tt>if () ... else ...</tt> clauses yourself), and also functions
+ * and classes offering ways to control the appearance of the output
+ * by setting flags for each output format.
+ *
+ *
+ * <h3>Information for derived classes</h3>
+ *
+ * What is actually missing this class is a way to produce the patches
+ * for output itself, from the stored data and degree of freedom
+ * information.  Since this task is often application dependent it is
+ * left to derived classes. For example, in many applications, it
+ * might be wanted to limit the depth of output to a certain number of
+ * refinement levels and write data from finer cells only in a way
+ * interpolated to coarser cells, to reduce the amount of
+ * output. Also, it might be wanted to use different numbers of
+ * subdivisions on different cells when forming a patch, for example
+ * to accomplish for different polynomial degrees of the trial space
+ * on different cells. Also, the output need not necessarily consist
+ * of a patch for each cell, but might be made up of patches for
+ * faces, of other things. Take a look at derived classes to what is
+ * possible in this respect.
+ *
+ * For this reason, it is left to a derived class to provide a
+ * function, named usually build_patches() or the like, which fills
+ * the #patches array of this class.
+ *
+ * Regarding the templates of this class, it needs three values: first
+ * the space dimension in which the triangulation and the DoF handler
+ * operate, second the dimension of the objects which the patches
+ * represent.  Although in most cases they are equal, there are also
+ * classes for which this does not hold, for example if one outputs
+ * the result of a computation exploiting rotational symmetry in the
+ * original domain (in which the space dimension of the output would
+ * be one higher than that of the DoF handler, see the
+ * DataOut_Rotation() class), or one might conceive that one could
+ * write a class that only outputs the solution on a cut through the
+ * domain, in which case the space dimension of the output is less
+ * than that of the DoF handler. The last template argument denotes
+ * the dimension of the space into which the patches are embedded;
+ * usually, this dimension is the same as the dimensio of the patches
+ * themselves (which is also the default value of the template
+ * parameter), but there might be cases where this is not so. For
+ * example, in the DataOut_Faces() class, patches are generated
+ * from faces of the triangulation. Thus, the dimension of the patch
+ * is one less than the dimension of the embedding space, which is, in
+ * this case, equal to the dimension of the triangulation and DoF
+ * handler. However, for the cut through the domain mentioned above,
+ * if the cut is a straight one, then the cut can be embedded into a
+ * space of one dimension lower than the dimension of the
+ * triangulation, so that the last template parameter has the same
+ * value as the second one.
+ *
+ * @ingroup output
+ * @author Wolfgang Bangerth, 1999
+ */
+template <class DH, int patch_dim, int patch_space_dim=patch_dim>
+class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
+{
+public:
+
+  /**
+   * Typedef to the iterator type of the dof handler class under
+   * consideration.
+   */
+  typedef typename Triangulation<DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
+  typedef typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
+
+public:
+
+  /**
+   * Type describing what the vector given to add_data_vector() is: a vector
+   * that has one entry per degree of freedom in a DoFHandler object (such as
+   * solution vectors), or one entry per cell in the triangulation underlying
+   * the DoFHandler object (such as error per cell data). The value
+   * #type_automatic tells add_data_vector() to find out itself (see the
+   * documentation of add_data_vector() for the method used).
+   */
+  enum DataVectorType
+  {
+    /**
+     * Data vector entries are associated to degrees of freedom
+     */
+    type_dof_data,
+
+    /**
+     * Data vector entries are one per grid cell
+     */
+    type_cell_data,
+
+    /**
+     * Find out automatically
+     */
+    type_automatic
+  };
+
+  /**
+   * Constructor
+   */
+  DataOut_DoFData ();
+
+  /**
+   * Destructor.
+   */
+  virtual ~DataOut_DoFData ();
+
+  /**
+   * Designate a dof handler to be used to extract geometry data and the
+   * mapping between nodes and node values. This call is not necessary if all
+   * added data vectors are supplemented with a DoFHandler argument.
+   *
+   * This call is optional: If you add data vectors with specified DoFHandler
+   * object, then that contains all information needed to generate the output.
+   */
+  void attach_dof_handler (const DH &);
+
+  /**
+   * Designate a triangulation to be used to extract geometry data and the
+   * mapping between nodes and node values.
+   *
+   * This call is optional: If you add data vectors with specified DoFHandler
+   * object, then that contains all information needed to generate the
+   * output. This call is useful when you only output cell vectors and no
+   * DoFHandler at all, in which case it provides the geometry.
+   */
+  void attach_triangulation (const Triangulation<DH::dimension,
+                             DH::space_dimension> &);
+
+  /**
+   * Add a data vector together with its name.
+   *
+   * A pointer to the vector is stored, so you have to make sure the vector
+   * exists at that address at least as long as you call the <tt>write_*</tt>
+   * functions.
+   *
+   * It is assumed that the vector has the same number of components as there
+   * are degrees of freedom in the dof handler, in which case it is assumed to
+   * be a vector storing nodal data; or the size may be the number of active
+   * cells on the present grid, in which case it is assumed to be a cell data
+   * vector. As the number of degrees of freedom and of cells is usually not
+   * equal, the function can determine itself which type of vector it is
+   * given. However, there are corner cases where this automatic determination
+   * does not work.  One example is if you compute with piecewise constant
+   * elements and have a scalar solution, then there are as many cells as
+   * there are degrees of freedom (though they may be numbered
+   * differently). Another possibility is if you have a 1d mesh embedded in 2d
+   * space and the mesh consists of a closed curve of cells; in this case,
+   * there are as many nodes as there are cells, and when using a Q1 element
+   * you will have as many degrees of freedom as there are cells.  In these
+   * cases, you can change the last argument of the function from its default
+   * value #type_automatic to either #type_dof_data or #type_cell_data,
+   * depending on what the vector represents. Apart from such corner cases,
+   * you can leave the argument at its default value and let the function
+   * determine the type of the vector itself.
+   *
+   * If it is a vector holding DoF data, the names given shall be one for each
+   * component of the underlying finite element.  If it is a finite element
+   * composed of only one subelement, then there is another function following
+   * which takes a single name instead of a vector of names.
+   *
+   * The data_component_interpretation argument contains information about how
+   * the individual components of output files that consist of more than one
+   * data set are to be interpreted.
+   *
+   * For example, if one has a finite element for the Stokes equations in 2d,
+   * representing components (u,v,p), one would like to indicate that the
+   * first two, u and v, represent a logical vector so that later on when we
+   * generate graphical output we can hand them off to a visualization program
+   * that will automatically know to render them as a vector field, rather
+   * than as two separate and independent scalar fields.
+   *
+   * The default value of this argument (i.e. an empty vector) corresponds is
+   * equivalent to a vector of values
+   * DataComponentInterpretation::component_is_scalar, indicating that all
+   * output components are independent scalar fields. However, if the given
+   * data vector represents logical vectors, you may pass a vector that
+   * contains values
+   * DataComponentInterpretation::component_is_part_of_vector. In the example
+   * above, one would pass in a vector with components
+   * (DataComponentInterpretation::component_is_part_of_vector,
+   * DataComponentInterpretation::component_is_part_of_vector,
+   * DataComponentInterpretation::component_is_scalar) for (u,v,p).
+   *
+   * The names of a data vector shall only contain characters which are
+   * letters, underscore and a few other ones. Refer to the
+   * ExcInvalidCharacter exception declared in this class to see which
+   * characters are valid and which are not.
+   *
+   * @note The actual type for the vector argument may be any vector type from
+   * which FEValues can extract values on a cell using the
+   * FEValuesBase::get_function_values() function. In particular, this
+   * includes all of the usual vector types, but also IndexSet (see step-41
+   * for a use of this).
+   */
+  template <class VECTOR>
+  void add_data_vector (const VECTOR                   &data,
+                        const std::vector<std::string> &names,
+                        const DataVectorType            type = type_automatic,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+  /**
+   * This function is an abbreviation to the above one (see there for a
+   * discussion of the various arguments), intended for use with finite
+   * elements that are not composed of subelements. In this case, only one
+   * name per data vector needs to be given, which is what this function
+   * takes. It simply relays its arguments after a conversion of the @p name
+   * to a vector of strings, to the other add_data_vector() function above.
+   *
+   * If @p data is a vector with multiple components this function will
+   * generate distinct names for all components by appending an underscore and
+   * the number of each component to @p name
+   *
+   * The actual type for the template argument may be any vector type from
+   * which FEValues can extract values on a cell using the
+   * FEValuesBase::get_function_values() function.
+   */
+  template <class VECTOR>
+  void add_data_vector (const VECTOR         &data,
+                        const std::string    &name,
+                        const DataVectorType  type = type_automatic,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+  /**
+   * This function is an extension of the above one (see there for a
+   * discussion of the arguments except the first one) and allows to set a
+   * vector with its own DoFHandler object. This DoFHandler needs to be
+   * compatible with the other DoFHandler objects assigned with calls to @p
+   * add_data_vector or @p attach_dof_handler, in the sense that the
+   * DoFHandler objects need to be based on the same triangulation. This
+   * function allows you to export data from multiple DoFHandlers that
+   * describe different solution components.
+   *
+   * Since this function takes a DoFHandler object and hence naturally
+   * represents dof data, the data vector type argument present in the other
+   * methods above is skipped.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                       &dof_handler,
+                        const VECTOR                   &data,
+                        const std::vector<std::string> &names,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+
+  /**
+   * This function is an abbreviation of the function above with only a scalar
+   * @p dof_handler given and a single data name.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                       &dof_handler,
+                        const VECTOR                   &data,
+                        const std::string              &name,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+  /**
+   * This function is an alternative to the above ones, allowing the output of
+   * derived quantities instead of the given data. This converison has to be
+   * done in a class derived from DataPostprocessor.
+   *
+   * The names for these derived quantities are provided by the @p
+   * data_postprocessor argument. Likewise, the data_component_interpretation
+   * argument of the other add_data_vector() functions is provided by the
+   * data_postprocessor argument. As only data of type @p type_dof_data can be
+   * transformed, this type is also known implicitly and does not have to be
+   * given.
+   *
+   * @note The actual type for the vector argument may be any vector type from
+   * which FEValues can extract values on a cell using the
+   * FEValuesBase::get_function_values() function. In particular, this
+   * includes all of the usual vector types, but also IndexSet (see step-41
+   * for a use of this).
+   */
+  template <class VECTOR>
+  void add_data_vector (const VECTOR                           &data,
+                        const DataPostprocessor<DH::space_dimension> &data_postprocessor);
+
+  /**
+   * Same function as above, but with a DoFHandler object that does not need
+   * to coincide with the DoFHandler initially set. Note that the
+   * postprocessor can only read data from the given DoFHandler and solution
+   * vector, not other solution vectors or DoFHandlers.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                               &dof_handler,
+                        const VECTOR                           &data,
+                        const DataPostprocessor<DH::space_dimension> &data_postprocessor);
+
+  /**
+   * Release the pointers to the data vectors. This allows output of a new set
+   * of vectors without supplying the DoF handler again. Therefore, the
+   * DataOut object can be used in an algebraic context. Note that besides the
+   * data vectors also the patches already computed are deleted.
+   */
+  void clear_data_vectors ();
+
+  /**
+   * Release pointers to all input data elements, i.e. pointers to data
+   * vectors and to the DoF handler object. This function may be useful when
+   * you have called the @p build_patches function of derived class, since
+   * then the patches are built and the input data is no more needed, nor is
+   * there a need to reference it. You can then output the patches detached
+   * from the main thread and need not make sure anymore that the DoF handler
+   * object and vectors must not be deleted before the output thread is
+   * finished.
+   */
+  void clear_input_data_references ();
+
+  /**
+   * This function can be used to merge the patches that were created using
+   * the @p build_patches function of the object given as argument into the
+   * list of patches created by this object. This is sometimes handy if one
+   * has, for example, a domain decomposition algorithm where each block is
+   * represented by a DoFHandler of its own, but one wants to output the
+   * solution on all the blocks at the same time.
+   *
+   * For this to work, the given argument and this object need to have the
+   * same number of output vectors, and they need to use the same number of
+   * subdivisions per patch. The output will probably look rather funny if
+   * patches in both objects overlap in space.
+   *
+   * If you call build_patches() for this object after merging in patches, the
+   * previous state is overwritten, and the merged-in patches are lost.
+   *
+   * The second parameter allows to shift each node of the patches in the
+   * object passed in in the first parameter by a certain amount. This is
+   * sometimes useful to generate "exploded" views of a collection of blocks.
+   *
+   * This function will fail if either this or the other object did not yet
+   * set up any patches.
+   */
+  template <class DH2>
+  void merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
+                      const Point<patch_space_dim> &shift = Point<patch_space_dim>());
+
+  /**
+   * Release the pointers to the data vectors and the DoF handler. You have to
+   * set all data entries again using the add_data_vector() function. The
+   * pointer to the dof handler is cleared as well, along with all other
+   * data. In effect, this function resets everything to a virgin state.
+   */
+  virtual void clear ();
+
+  /**
+   * Determine an estimate for the memory consumption (in bytes) of this
+   * object.
+   */
+  std::size_t memory_consumption () const;
+
+  /**
+   * Exception
+   */
+  DeclException0 (ExcNoTriangulationSelected);
+
+  /**
+   * Exception
+   */
+  DeclException0 (ExcNoDoFHandlerSelected);
+
+  /**
+   * Exception
+   */
+  DeclException0 (ExcDataPostprocessingIsNotPossibleForCellData);
+
+  /**
+   * Exception
+   */
+  DeclException3 (ExcInvalidVectorSize,
+                  int, int, int,
+                  << "The vector has size " << arg1
+                  << " but the DoFHandler objects says there are " << arg2
+                  << " degrees of freedom and there are " << arg3
+                  << " active cells.");
+  /**
+   * Exception
+   */
+  DeclException2 (ExcInvalidCharacter,
+                  std::string, size_t,
+                  << "Please use only the characters [a-zA-Z0-9_<>()] for" << std::endl
+                  << "description strings since some graphics formats will only accept these."
+                  << std::endl
+                  << "The string you gave was <" << arg1
+                  << ">, the invalid character is <" << arg1[arg2]
+                  << ">." << std::endl);
+  /**
+   * Exception
+   */
+  DeclException0 (ExcOldDataStillPresent);
+  /**
+   * Exception
+   */
+  DeclException2 (ExcInvalidNumberOfNames,
+                  int, int,
+                  << "You have to give one name per component in your "
+                  << "data vector. The number you gave was " << arg1
+                  << ", but the number of components is " << arg2);
+  /**
+   * Exception
+   */
+  DeclException0 (ExcNoPatches);
+  /**
+   * Exception
+   */
+  DeclException0 (ExcIncompatibleDatasetNames);
+  /**
+   * Exception
+   */
+  DeclException0 (ExcIncompatiblePatchLists);
+
+  DeclException2 (ExcInvalidVectorDeclaration,
+                  int, std::string,
+                  << "When declaring that a number of components in a data\n"
+                  << "set to be output logically form a vector instead of\n"
+                  << "simply a set of scalar fields, you need to specify\n"
+                  << "this for all relevant components. Furthermore,\n"
+                  << "vectors must always consist of exactly <dim>\n"
+                  << "components. However, the vector component at\n"
+                  << "position " << arg1 << " with name <" << arg2
+                  << "> does not satisfy these conditions.");
+
+protected:
+  /**
+   * Abbreviate the somewhat lengthy name for the Patch class.
+   */
+  typedef dealii::DataOutBase::Patch<patch_dim,patch_space_dim> Patch;
+
+  /**
+   * Pointer to the triangulation object.
+   */
+  SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> > triangulation;
+
+  /**
+   * Pointer to the optional handler object.
+   */
+  SmartPointer<const DH> dofs;
+
+  /**
+   * List of data elements with vectors of values for each degree of freedom.
+   */
+  std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  dof_data;
+
+  /**
+   * List of data elements with vectors of values for each cell.
+   */
+  std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  cell_data;
+
+  /**
+   * This is a list of patches that is created each time build_patches() is
+   * called. These patches are used in the output routines of the base
+   * classes.
+   */
+  std::vector<Patch> patches;
+
+  /**
+   * Function by which the base class's functions get to know what patches
+   * they shall write to a file.
+   */
+  virtual
+  const std::vector<Patch> &get_patches () const;
+
+  /**
+   * Virtual function through which the names of data sets are obtained by the
+   * output functions of the base class.
+   */
+  virtual
+  std::vector<std::string> get_dataset_names () const;
+
+  /**
+   * Extracts the finite elements stored in the dof_data object, including a
+   * dummy object of FE_DGQ<dim>(0) in case only the triangulation is used.
+   */
+  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
+  get_finite_elements() const;
+
+  /**
+   * Overload of the respective DataOutInterface::get_vector_data_ranges()
+   * function. See there for a more extensive documentation.
+   */
+  virtual
+  std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
+  get_vector_data_ranges () const;
+
+  /**
+   * Make all template siblings friends. Needed for the merge_patches()
+   * function.
+   */
+  template <class, int, int>
+  friend class DataOut_DoFData;
+};
+
+
+
+// -------------------- template and inline functions ------------------------
+
+
+template <class DH, int patch_dim, int patch_space_dim>
+template <class DH2>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
+               const Point<patch_space_dim> &shift)
+{
+  const std::vector<Patch> source_patches = source.get_patches ();
+  Assert (patches.size () != 0,        ExcNoPatches ());
+  Assert (source_patches.size () != 0, ExcNoPatches ());
+  // check equality of component
+  // names
+  Assert (get_dataset_names() == source.get_dataset_names(),
+          ExcIncompatibleDatasetNames());
+  // make sure patches are compatible. we'll
+  // assume that if the first respective
+  // patches are ok that all the other ones
+  // are ok as well
+  Assert (patches[0].n_subdivisions == source_patches[0].n_subdivisions,
+          ExcIncompatiblePatchLists());
+  Assert (patches[0].data.n_rows() == source_patches[0].data.n_rows(),
+          ExcIncompatiblePatchLists());
+  Assert (patches[0].data.n_cols() == source_patches[0].data.n_cols(),
+          ExcIncompatiblePatchLists());
+
+  // check equality of the vector data
+  // specifications
+  Assert (get_vector_data_ranges().size() ==
+          source.get_vector_data_ranges().size(),
+          ExcMessage ("Both sources need to declare the same components "
+                      "as vectors."));
+  for (unsigned int i=0; i<get_vector_data_ranges().size(); ++i)
+    {
+      Assert (std_cxx1x::get<0>(get_vector_data_ranges()[i]) ==
+              std_cxx1x::get<0>(source.get_vector_data_ranges()[i]),
+              ExcMessage ("Both sources need to declare the same components "
+                          "as vectors."));
+      Assert (std_cxx1x::get<1>(get_vector_data_ranges()[i]) ==
+              std_cxx1x::get<1>(source.get_vector_data_ranges()[i]),
+              ExcMessage ("Both sources need to declare the same components "
+                          "as vectors."));
+      Assert (std_cxx1x::get<2>(get_vector_data_ranges()[i]) ==
+              std_cxx1x::get<2>(source.get_vector_data_ranges()[i]),
+              ExcMessage ("Both sources need to declare the same components "
+                          "as vectors."));
+    }
+
+  // merge patches. store old number
+  // of elements, since we need to
+  // adjust patch numbers, etc
+  // afterwards
+  const unsigned int old_n_patches = patches.size();
+  patches.insert (patches.end(),
+                  source_patches.begin(),
+                  source_patches.end());
+
+  // perform shift, if so desired
+  if (shift != Point<patch_space_dim>())
+    for (unsigned int i=old_n_patches; i<patches.size(); ++i)
+      for (unsigned int v=0; v<GeometryInfo<patch_dim>::vertices_per_cell; ++v)
+        patches[i].vertices[v] += shift;
+
+  // adjust patch numbers
+  for (unsigned int i=old_n_patches; i<patches.size(); ++i)
+    patches[i].patch_index += old_n_patches;
+
+  // adjust patch neighbors
+  for (unsigned int i=old_n_patches; i<patches.size(); ++i)
+    for (unsigned int n=0; n<GeometryInfo<patch_dim>::faces_per_cell; ++n)
+      if (patches[i].neighbors[n] != Patch::no_neighbor)
+        patches[i].neighbors[n] += old_n_patches;
+}
+
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
index 1a45fd3fbb30dfb2d503e52ae699e6ff65a0d08c..bdf5a847783a28d0e6a76765e23d4e14db190f19 100644 (file)
@@ -19,7 +19,7 @@
 
 
 #include <deal.II/base/config.h>
-#include <deal.II/numerics/data_out.h>
+#include <deal.II/numerics/data_out_dof_data.h>
 
 #include <string>
 #include <vector>
index f47c98b30b0d3ce07c08c40ecfcd1fe49c3a9d88..6f15d97c2e759c8af141e3982cc2cfd6f5c9b5ac 100644 (file)
@@ -234,114 +234,59 @@ class KellyErrorEstimator
 {
 public:
   /**
-   * Implementation of the error
-   * estimator described above. You
-   * may give a coefficient, but
-   * there is a default value which
-   * denotes the constant
-   * coefficient with value
-   * one. The coefficient function
-   * may either be a scalar one, in
-   * which case it is used for all
-   * components of the finite
-   * element, or a vector-valued
-   * one with as many components as
-   * there are in the finite
-   * element; in the latter case,
-   * each component is weighted by
-   * the respective component in
-   * the coefficient.
+   * Implementation of the error estimator described above. You may give a
+   * coefficient, but there is a default value which denotes the constant
+   * coefficient with value one. The coefficient function may either be a
+   * scalar one, in which case it is used for all components of the finite
+   * element, or a vector-valued one with as many components as there are in
+   * the finite element; in the latter case, each component is weighted by the
+   * respective component in the coefficient.
    *
-   * You might give a list of
-   * components you want to
-   * evaluate, in case the finite
-   * element used by the
-   * DoFHandler object is
-   * vector-valued. You then have
-   * to set those entries to true
-   * in the bit-vector
-   * @p component_mask
-   * (see @ref GlossComponentMask)
-   * for which the
-   * respective component is to be
-   * used in the error
-   * estimator. The default is to
-   * use all components, which is
-   * done by either providing a
-   * bit-vector with all-set
-   * entries, or an empty
-   * bit-vector.
+   * You might give a list of components you want to evaluate, in case the
+   * finite element used by the DoFHandler object is vector-valued. You then
+   * have to set those entries to true in the bit-vector @p component_mask
+   * (see @ref GlossComponentMask) for which the respective component is to be
+   * used in the error estimator. The default is to use all components, which
+   * is done by either providing a bit-vector with all-set entries, or an
+   * empty bit-vector.
    *
-   * The @p subdomain_id parameter
-   * indicates whether we shall compute
-   * indicators for all cells (in case its
-   * value is the default,
-   * <tt>numbers::invalid_unsigned_int</tt>),
-   * or only for the cells belonging to a
-   * certain subdomain with the given
-   * indicator. The latter case is used for
-   * parallel computations where all
-   * processor nodes have the global grid
-   * stored, and could well compute all the
-   * indicators for all cells themselves,
-   * but where it is more efficient to have
-   * each process compute only indicators
-   * for the cells it owns, and have them
-   * exchange the resulting information
-   * afterwards. This is in particular true
-   * for the case where meshes are very
-   * large and computing indicators for @em
-   * every cell is too expensive, while
-   * computing indicators for only local
-   * cells is acceptable. Note that if you
-   * only ask for the indicators of a
-   * certain subdomain to be computed, you
-   * must nevertheless make sure that this
-   * function has access to the correct
-   * node values of @em all degrees of
-   * freedom. This is since the function
-   * needs to access DoF values on
-   * neighboring cells as well, even if
-   * they belong to a different subdomain.
+   * The @p subdomain_id parameter indicates whether we shall compute
+   * indicators for all cells (in case its value is the default,
+   * <tt>numbers::invalid_unsigned_int</tt>), or only for the cells belonging
+   * to a certain subdomain with the given indicator. The latter case is used
+   * for parallel computations where all processor nodes have the global grid
+   * stored, and could well compute all the indicators for all cells
+   * themselves, but where it is more efficient to have each process compute
+   * only indicators for the cells it owns, and have them exchange the
+   * resulting information afterwards. This is in particular true for the case
+   * where meshes are very large and computing indicators for @em every cell
+   * is too expensive, while computing indicators for only local cells is
+   * acceptable. Note that if you only ask for the indicators of a certain
+   * subdomain to be computed, you must nevertheless make sure that this
+   * function has access to the correct node values of @em all degrees of
+   * freedom. This is since the function needs to access DoF values on
+   * neighboring cells as well, even if they belong to a different subdomain.
    *
-   * The @p material_id parameter has a similar
-   * meaning: if not set to its default value
-   * (which is numbers::invalid_material_id),
-   * it means that indicators will only be
-   * computed for cells with this particular
-   * material id.
+   * The @p material_id parameter has a similar meaning: if not set to its
+   * default value (which is numbers::invalid_material_id), it means that
+   * indicators will only be computed for cells with this particular material
+   * id.
    *
-   * The @p n_threads parameter used to
-   * indicate the number of threads to be
-   * used to compute the error
-   * estimator. This parameter is now
-   * ignored, with the number of threads
-   * determined automatically. The
-   * parameter is retained for
-   * compatibility with old versions of the
-   * library.
+   * The @p n_threads parameter used to indicate the number of threads to be
+   * used to compute the error estimator. This parameter is now ignored, with
+   * the number of threads determined automatically. The parameter is retained
+   * for compatibility with old versions of the library.
    *
-   * @note If the DoFHandler object
-   * given as an argument to this
-   * function builds on a
-   * parallel::distributed::Triangulation,
-   * this function skips
-   * computations on all cells that
-   * are not locally owned. In that
-   * case, the only valid value for
-   * the subdomain_id argument
-   * (besides the invalid value) is
-   * the subdomain id that is
-   * associated with the currently
+   * @note If the DoFHandler object given as an argument to this function
+   * builds on a parallel::distributed::Triangulation, this function skips
+   * computations on all cells that are not locally owned. In that case, the
+   * only valid value for the subdomain_id argument (besides the invalid
+   * value) is the subdomain id that is associated with the currently
    * processor, as reported by
    * parallel::distributed::Triangulation::locally_owned_subdomain(). Even
-   * though nothing is computed on
-   * cells that we don't locally
-   * own, the error indicator
-   * vector must still have a
-   * length equal to the number of
-   * active cell in the mesh as
-   * reported by
+   * though nothing is computed on cells that we don't locally own, the error
+   * indicator vector must still have a length equal to the number of active
+   * cell in the mesh as reported by
    * parallel::distributed::Triangulation::n_locally_owned_active_cells().
    */
   template <typename InputVector, class DH>
@@ -358,8 +303,7 @@ public:
                         const types::material_id       material_id = numbers::invalid_material_id);
 
   /**
-   * Calls the @p estimate
-   * function, see above, with
+   * Calls the @p estimate function, see above, with
    * <tt>mapping=MappingQ1@<dim@>()</tt>.
    */
   template <typename InputVector, class DH>
@@ -375,31 +319,17 @@ public:
                         const types::material_id       material_id = numbers::invalid_material_id);
 
   /**
-   * Same function as above, but
-   * accepts more than one solution
-   * vector and returns one error
-   * vector for each solution
-   * vector. For the reason of
-   * existence of this function,
-   * see the general documentation
-   * of this class.
+   * Same function as above, but accepts more than one solution vector and
+   * returns one error vector for each solution vector. For the reason of
+   * existence of this function, see the general documentation of this class.
    *
-   * Since we do not want to force
-   * the user of this function to
-   * copy around their solution
-   * vectors, the vector of
-   * solution vectors takes
-   * pointers to the solutions,
-   * rather than being a vector of
-   * vectors. This makes it simpler
-   * to have the solution vectors
-   * somewhere in memory, rather
-   * than to have them collected
-   * somewhere special. (Note that
-   * it is not possible to
-   * construct of vector of
-   * references, so we had to use a
-   * vector of pointers.)
+   * Since we do not want to force the user of this function to copy around
+   * their solution vectors, the vector of solution vectors takes pointers to
+   * the solutions, rather than being a vector of vectors. This makes it
+   * simpler to have the solution vectors somewhere in memory, rather than to
+   * have them collected somewhere special. (Note that it is not possible to
+   * construct of vector of references, so we had to use a vector of
+   * pointers.)
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<dim, spacedim>          &mapping,
@@ -415,8 +345,7 @@ public:
                         const types::material_id           material_id = numbers::invalid_material_id);
 
   /**
-   * Calls the @p estimate
-   * function, see above, with
+   * Calls the @p estimate function, see above, with
    * <tt>mapping=MappingQ1@<dim@>()</tt>.
    */
   template <typename InputVector, class DH>
@@ -433,10 +362,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<dim, spacedim>      &mapping,
@@ -453,10 +380,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const DH                &dof,
@@ -472,10 +397,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<dim, spacedim>          &mapping,
@@ -492,10 +415,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const DH                    &dof,
@@ -561,51 +482,28 @@ class KellyErrorEstimator<1,spacedim>
 {
 public:
   /**
-   * Implementation of the error
-   * estimator described above. You
-   * may give a coefficient, but
-   * there is a default value which
-   * denotes the constant
-   * coefficient with value
-   * one. The coefficient function
-   * may either be a scalar one, in
-   * which case it is used for all
-   * components of the finite
-   * element, or a vector-valued
-   * one with as many components as
-   * there are in the finite
-   * element; in the latter case,
-   * each component is weighted by
-   * the respective component in
-   * the coefficient.
+   * Implementation of the error estimator described above. You may give a
+   * coefficient, but there is a default value which denotes the constant
+   * coefficient with value one. The coefficient function may either be a
+   * scalar one, in which case it is used for all components of the finite
+   * element, or a vector-valued one with as many components as there are in
+   * the finite element; in the latter case, each component is weighted by the
+   * respective component in the coefficient.
    *
-   * You might give a list of components
-   * you want to evaluate, in case the
-   * finite element used by the DoFHandler
-   * object is vector-valued. You then have
-   * to set those entries to true in the
-   * bit-vector @p component_mask for which
-   * the respective component is to be used
-   * in the error estimator. The default is
-   * to use all components, which is done
-   * by either providing a bit-vector with
-   * all-set entries, or an empty
-   * bit-vector. All the other parameters
-   * are as in the general case used for 2d
-   * and higher.
+   * You might give a list of components you want to evaluate, in case the
+   * finite element used by the DoFHandler object is vector-valued. You then
+   * have to set those entries to true in the bit-vector @p component_mask for
+   * which the respective component is to be used in the error estimator. The
+   * default is to use all components, which is done by either providing a
+   * bit-vector with all-set entries, or an empty bit-vector. All the other
+   * parameters are as in the general case used for 2d and higher.
    *
-   * The estimator supports multithreading
-   * and splits the cells to
-   * <tt>multithread_info.n_default_threads</tt>
-   * (default) threads. The number of
-   * threads to be used in multithreaded
-   * mode can be set with the last
-   * parameter of the error estimator.
-   * Multithreading is not presently
-   * implemented for 1d, but we retain the
-   * respective parameter for compatibility
-   * with the function signature in the
-   * general case.
+   * The estimator supports multithreading and splits the cells to
+   * <tt>multithread_info.n_default_threads</tt> (default) threads. The number
+   * of threads to be used in multithreaded mode can be set with the last
+   * parameter of the error estimator.  Multithreading is not presently
+   * implemented for 1d, but we retain the respective parameter for
+   * compatibility with the function signature in the general case.
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<1,spacedim>  &mapping,
@@ -621,8 +519,7 @@ public:
                         const types::material_id       material_id = numbers::invalid_material_id);
 
   /**
-   * Calls the @p estimate
-   * function, see above, with
+   * Calls the @p estimate function, see above, with
    * <tt>mapping=MappingQ1<1>()</tt>.
    */
   template <typename InputVector, class DH>
@@ -638,31 +535,17 @@ public:
                         const types::material_id       material_id = numbers::invalid_material_id);
 
   /**
-   * Same function as above, but
-   * accepts more than one solution
-   * vectors and returns one error
-   * vector for each solution
-   * vector. For the reason of
-   * existence of this function,
-   * see the general documentation
-   * of this class.
+   * Same function as above, but accepts more than one solution vectors and
+   * returns one error vector for each solution vector. For the reason of
+   * existence of this function, see the general documentation of this class.
    *
-   * Since we do not want to force
-   * the user of this function to
-   * copy around their solution
-   * vectors, the vector of
-   * solution vectors takes
-   * pointers to the solutions,
-   * rather than being a vector of
-   * vectors. This makes it simpler
-   * to have the solution vectors
-   * somewhere in memory, rather
-   * than to have them collected
-   * somewhere special. (Note that
-   * it is not possible to
-   * construct of vector of
-   * references, so we had to use a
-   * vector of pointers.)
+   * Since we do not want to force the user of this function to copy around
+   * their solution vectors, the vector of solution vectors takes pointers to
+   * the solutions, rather than being a vector of vectors. This makes it
+   * simpler to have the solution vectors somewhere in memory, rather than to
+   * have them collected somewhere special. (Note that it is not possible to
+   * construct of vector of references, so we had to use a vector of
+   * pointers.)
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<1,spacedim>          &mapping,
@@ -678,8 +561,7 @@ public:
                         const types::material_id           material_id = numbers::invalid_material_id);
 
   /**
-   * Calls the @p estimate
-   * function, see above, with
+   * Calls the @p estimate function, see above, with
    * <tt>mapping=MappingQ1<1>()</tt>.
    */
   template <typename InputVector, class DH>
@@ -696,10 +578,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<1,spacedim>      &mapping,
@@ -716,10 +596,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const DH                &dof,
@@ -735,10 +613,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const Mapping<1,spacedim>          &mapping,
@@ -755,10 +631,8 @@ public:
 
 
   /**
-   * Equivalent to the set of functions
-   * above, except that this one takes a
-   * quadrature collection for hp finite
-   * element dof handlers.
+   * Equivalent to the set of functions above, except that this one takes a
+   * quadrature collection for hp finite element dof handlers.
    */
   template <typename InputVector, class DH>
   static void estimate (const DH                    &dof,
index d7cf41a6ed1579e8da9a9571a938605043a830d6..5cb317c4976aba105ed8f0926e15320a6a333489 100644 (file)
@@ -1404,300 +1404,173 @@ namespace VectorTools
 
 
   /**
-   * Compute the constraints that
-   * correspond to boundary conditions of
-   * the form $\vec n \cdot \vec u=0$,
-   * i.e. no normal flux if $\vec u$ is a
-   * vector-valued quantity. These
-   * conditions have exactly the form
-   * handled by the ConstraintMatrix class,
-   * so instead of creating a map between
-   * boundary degrees of freedom and
-   * corresponding value, we here create a
-   * list of constraints that are written
-   * into a ConstraintMatrix. This object
-   * may already have some content, for
-   * example from hanging node constraints,
-   * that remains untouched. These
-   * constraints have to be applied to the
-   * linear system like any other such
-   * constraints, i.e. you have to condense
-   * the linear system with the constraints
-   * before solving, and you have to
-   * distribute the solution vector
-   * afterwards.
-   *
-   * The use of this function is
-   * explained in more detail in
-   * step-31. It
-   * doesn't make much sense in 1d,
-   * so the function throws an
-   * exception in that case.
-   *
-   * The second argument of this
-   * function denotes the first
-   * vector component in the finite
-   * element that corresponds to
-   * the vector function that you
-   * want to constrain. For
-   * example, if we were solving a
-   * Stokes equation in 2d and the
-   * finite element had components
-   * $(u,v,p)$, then @p
-   * first_vector_component would
-   * be zero. On the other hand, if
-   * we solved the Maxwell
-   * equations in 3d and the finite
-   * element has components
-   * $(E_x,E_y,E_z,B_x,B_y,B_z)$
-   * and we want the boundary
-   * condition $\vec n\cdot \vec
-   * B=0$, then @p
-   * first_vector_component would
-   * be 3. Vectors are implicitly
-   * assumed to have exactly
-   * <code>dim</code> components
-   * that are ordered in the same
-   * way as we usually order the
-   * coordinate directions,
-   * i.e. $x$-, $y$-, and finally
-   * $z$-component. The function
-   * assumes, but can't check, that
-   * the vector components in the
-   * range
-   * <code>[first_vector_component,first_vector_component+dim)</code>
-   * come from the same base finite
-   * element. For example, in the
-   * Stokes example above, it would
-   * not make sense to use a
-   * <code>FESystem@<dim@>(FE_Q@<dim@>(2),
-   * 1, FE_Q@<dim@>(1), dim)</code>
-   * (note that the first velocity
-   * vector component is a $Q_2$
-   * element, whereas all the other
-   * ones are $Q_1$ elements) as
-   * there would be points on the
-   * boundary where the
-   * $x$-velocity is defined but no
-   * corresponding $y$- or
-   * $z$-velocities.
-   *
-   * The third argument denotes the set of
-   * boundary indicators on which the
-   * boundary condition is to be
-   * enforced. Note that, as explained
-   * below, this is one of the few
-   * functions where it makes a difference
-   * where we call the function multiple
-   * times with only one boundary
-   * indicator, or whether we call the
-   * function onces with the whole set of
-   * boundary indicators at once.
-   *
-   * The mapping argument is used to
-   * compute the boundary points where the function
-   * needs to request the normal vector $\vec n$
-   * from the boundary description.
-   *
-   * @note When combining adaptively
-   * refined meshes with hanging node
-   * constraints and boundary conditions
-   * like from the current function within
-   * one ConstraintMatrix object, the
-   * hanging node constraints should always
-   * be set first, and then the boundary
-   * conditions since boundary conditions
-   * are not set in the second operation on
-   * degrees of freedom that are already
-   * constrained. This makes sure that the
-   * discretization remains conforming as
-   * is needed. See the discussion on
-   * conflicting constraints in the module
-   * on @ref constraints .
+   * Compute the constraints that correspond to boundary conditions of the
+   * form $\vec n \cdot \vec u=0$, i.e. no normal flux if $\vec u$ is a
+   * vector-valued quantity. These conditions have exactly the form handled by
+   * the ConstraintMatrix class, so instead of creating a map between boundary
+   * degrees of freedom and corresponding value, we here create a list of
+   * constraints that are written into a ConstraintMatrix. This object may
+   * already have some content, for example from hanging node constraints,
+   * that remains untouched. These constraints have to be applied to the
+   * linear system like any other such constraints, i.e. you have to condense
+   * the linear system with the constraints before solving, and you have to
+   * distribute the solution vector afterwards.
+   *
+   * The use of this function is explained in more detail in step-31. It
+   * doesn't make much sense in 1d, so the function throws an exception in
+   * that case.
+   *
+   * The second argument of this function denotes the first vector component
+   * in the finite element that corresponds to the vector function that you
+   * want to constrain. For example, if we were solving a Stokes equation in
+   * 2d and the finite element had components $(u,v,p)$, then @p
+   * first_vector_component would be zero. On the other hand, if we solved the
+   * Maxwell equations in 3d and the finite element has components
+   * $(E_x,E_y,E_z,B_x,B_y,B_z)$ and we want the boundary condition $\vec
+   * n\cdot \vec B=0$, then @p first_vector_component would be 3. Vectors are
+   * implicitly assumed to have exactly <code>dim</code> components that are
+   * ordered in the same way as we usually order the coordinate directions,
+   * i.e. $x$-, $y$-, and finally $z$-component. The function assumes, but
+   * can't check, that the vector components in the range
+   * <code>[first_vector_component,first_vector_component+dim)</code> come
+   * from the same base finite element. For example, in the Stokes example
+   * above, it would not make sense to use a
+   * <code>FESystem@<dim@>(FE_Q@<dim@>(2), 1, FE_Q@<dim@>(1), dim)</code>
+   * (note that the first velocity vector component is a $Q_2$ element,
+   * whereas all the other ones are $Q_1$ elements) as there would be points
+   * on the boundary where the $x$-velocity is defined but no corresponding
+   * $y$- or $z$-velocities.
+   *
+   * The third argument denotes the set of boundary indicators on which the
+   * boundary condition is to be enforced. Note that, as explained below, this
+   * is one of the few functions where it makes a difference where we call the
+   * function multiple times with only one boundary indicator, or whether we
+   * call the function onces with the whole set of boundary indicators at
+   * once.
+   *
+   * The mapping argument is used to compute the boundary points where the
+   * function needs to request the normal vector $\vec n$ from the boundary
+   * description.
+   *
+   * @note When combining adaptively refined meshes with hanging node
+   * constraints and boundary conditions like from the current function within
+   * one ConstraintMatrix object, the hanging node constraints should always
+   * be set first, and then the boundary conditions since boundary conditions
+   * are not set in the second operation on degrees of freedom that are
+   * already constrained. This makes sure that the discretization remains
+   * conforming as is needed. See the discussion on conflicting constraints in
+   * the module on @ref constraints .
    *
    *
    * <h4>Computing constraints in 2d</h4>
    *
-   * Computing these constraints requires
-   * some smarts. The main question
-   * revolves around the question what the
-   * normal vector is. Consider the
-   * following situation:
-   * <p ALIGN="center">
-   * @image html no_normal_flux_1.png
+   * Computing these constraints requires some smarts. The main question
+   * revolves around the question what the normal vector is. Consider the
+   * following situation: <p ALIGN="center"> @image html no_normal_flux_1.png
    * </p>
    *
-   * Here, we have two cells that use a
-   * bilinear mapping
-   * (i.e. MappingQ1). Consequently, for
-   * each of the cells, the normal vector
-   * is perpendicular to the straight
-   * edge. If the two edges at the top and
-   * right are meant to approximate a
-   * curved boundary (as indicated by the
-   * dashed line), then neither of the two
-   * computed normal vectors are equal to
-   * the exact normal vector (though they
-   * approximate it as the mesh is refined
-   * further). What is worse, if we
-   * constrain $\vec n \cdot \vec u=0$ at
-   * the common vertex with the normal
-   * vector from both cells, then we
-   * constrain the vector $\vec u$ with
-   * respect to two linearly independent
-   * vectors; consequently, the constraint
-   * would be $\vec u=0$ at this point
-   * (i.e. <i>all</i> components of the
-   * vector), which is not what we wanted.
-   *
-   * To deal with this situation, the
-   * algorithm works in the following way:
-   * at each point where we want to
-   * constrain $\vec u$, we first collect
-   * all normal vectors that adjacent cells
-   * might compute at this point. We then
-   * do not constrain $\vec n \cdot \vec
-   * u=0$ for <i>each</i> of these normal
-   * vectors but only for the
-   * <i>average</i> of the normal
-   * vectors. In the example above, we
-   * therefore record only a single
-   * constraint $\vec n \cdot \vec {\bar
-   * u}=0$, where $\vec {\bar u}$ is the
-   * average of the two indicated normal
-   * vectors.
-   *
-   * Unfortunately, this is not quite
-   * enough. Consider the situation here:
+   * Here, we have two cells that use a bilinear mapping
+   * (i.e. MappingQ1). Consequently, for each of the cells, the normal vector
+   * is perpendicular to the straight edge. If the two edges at the top and
+   * right are meant to approximate a curved boundary (as indicated by the
+   * dashed line), then neither of the two computed normal vectors are equal
+   * to the exact normal vector (though they approximate it as the mesh is
+   * refined further). What is worse, if we constrain $\vec n \cdot \vec u=0$
+   * at the common vertex with the normal vector from both cells, then we
+   * constrain the vector $\vec u$ with respect to two linearly independent
+   * vectors; consequently, the constraint would be $\vec u=0$ at this point
+   * (i.e. <i>all</i> components of the vector), which is not what we wanted.
+   *
+   * To deal with this situation, the algorithm works in the following way: at
+   * each point where we want to constrain $\vec u$, we first collect all
+   * normal vectors that adjacent cells might compute at this point. We then
+   * do not constrain $\vec n \cdot \vec u=0$ for <i>each</i> of these normal
+   * vectors but only for the <i>average</i> of the normal vectors. In the
+   * example above, we therefore record only a single constraint $\vec n \cdot
+   * \vec {\bar u}=0$, where $\vec {\bar u}$ is the average of the two
+   * indicated normal vectors.
+   *
+   * Unfortunately, this is not quite enough. Consider the situation here:
    *
    * <p ALIGN="center">
    * @image html no_normal_flux_2.png
    * </p>
    *
-   * If again the top and right edges
-   * approximate a curved boundary, and the
-   * left boundary a separate boundary (for
-   * example straight) so that the exact
-   * boundary has indeed a corner at the
-   * top left vertex, then the above
-   * construction would not work: here, we
-   * indeed want the constraint that $\vec
-   * u$ at this point (because the normal
-   * velocities with respect to both the
-   * left normal as well as the top normal
-   * vector should be zero), not that the
-   * velocity in the direction of the
-   * average normal vector is zero.
-   *
-   * Consequently, we use the following
-   * heuristic to determine whether all
-   * normal vectors computed at one point
-   * are to be averaged: if two normal
-   * vectors for the same point are
-   * computed on <i>different</i> cells,
-   * then they are to be averaged. This
-   * covers the first example above. If
-   * they are computed from the same cell,
-   * then the fact that they are different
-   * is considered indication that they
-   * come from different parts of the
-   * boundary that might be joined by a
-   * real corner, and must not be averaged.
-   *
-   * There is one problem with this
-   * scheme. If, for example, the same
-   * domain we have considered above, is
-   * discretized with the following mesh,
-   * then we get into trouble:
+   * If again the top and right edges approximate a curved boundary, and the
+   * left boundary a separate boundary (for example straight) so that the
+   * exact boundary has indeed a corner at the top left vertex, then the above
+   * construction would not work: here, we indeed want the constraint that
+   * $\vec u$ at this point (because the normal velocities with respect to
+   * both the left normal as well as the top normal vector should be zero),
+   * not that the velocity in the direction of the average normal vector is
+   * zero.
+   *
+   * Consequently, we use the following heuristic to determine whether all
+   * normal vectors computed at one point are to be averaged: if two normal
+   * vectors for the same point are computed on <i>different</i> cells, then
+   * they are to be averaged. This covers the first example above. If they are
+   * computed from the same cell, then the fact that they are different is
+   * considered indication that they come from different parts of the boundary
+   * that might be joined by a real corner, and must not be averaged.
+   *
+   * There is one problem with this scheme. If, for example, the same domain
+   * we have considered above, is discretized with the following mesh, then we
+   * get into trouble:
    *
    * <p ALIGN="center">
    * @image html no_normal_flux_3.png
    * </p>
    *
-   * Here, the algorithm assumes that the
-   * boundary does not have a corner at the
-   * point where faces $F1$ and $F2$ join
-   * because at that point there are two
-   * different normal vectors computed from
-   * different cells. If you intend for
-   * there to be a corner of the exact
-   * boundary at this point, the only way
-   * to deal with this is to assign the two
-   * parts of the boundary different
-   * boundary indicators and call this
-   * function twice, once for each boundary
-   * indicators; doing so will yield only
-   * one normal vector at this point per
-   * invocation (because we consider only
-   * one boundary part at a time), with the
-   * result that the normal vectors will
-   * not be averaged.
+   * Here, the algorithm assumes that the boundary does not have a corner at
+   * the point where faces $F1$ and $F2$ join because at that point there are
+   * two different normal vectors computed from different cells. If you intend
+   * for there to be a corner of the exact boundary at this point, the only
+   * way to deal with this is to assign the two parts of the boundary
+   * different boundary indicators and call this function twice, once for each
+   * boundary indicators; doing so will yield only one normal vector at this
+   * point per invocation (because we consider only one boundary part at a
+   * time), with the result that the normal vectors will not be averaged. This
+   * situation also needs to be taken into account when using this function
+   * around reentrant corners on Cartesian meshes. If no-normal-flux boundary
+   * conditions are to be enforced on non-Cartesian meshes around reentrant
+   * corners, one may even get cycles in the constraints as one will in
+   * general constrain different components from the two sides. In that case,
+   * set a no-slip constraint on the reentrant vertex first.
    *
    *
    * <h4>Computing constraints in 3d</h4>
    *
-   * The situation is more
-   * complicated in 3d. Consider
-   * the following case where we
-   * want to compute the
-   * constraints at the marked
-   * vertex:
+   * The situation is more complicated in 3d. Consider the following case
+   * where we want to compute the constraints at the marked vertex:
    *
    * <p ALIGN="center">
    * @image html no_normal_flux_4.png
    * </p>
    *
-   * Here, we get four different
-   * normal vectors, one from each
-   * of the four faces that meet at
-   * the vertex. Even though they
-   * may form a complete set of
-   * vectors, it is not our intent
-   * to constrain all components of
-   * the vector field at this
-   * point. Rather, we would like
-   * to still allow tangential
-   * flow, where the term
-   * "tangential" has to be
-   * suitably defined.
-   *
-   * In a case like this, the
-   * algorithm proceeds as follows:
-   * for each cell that has
-   * computed two tangential
-   * vectors at this point, we
-   * compute the unconstrained
-   * direction as the outer product
-   * of the two tangential vectors
-   * (if necessary multiplied by
-   * minus one). We then average
-   * these tangential
-   * vectors. Finally, we compute
-   * constraints for the two
-   * directions perpendicular to
-   * this averaged tangential
-   * direction.
-   *
-   * There are cases where one cell
-   * contributes two tangential
-   * directions and another one
-   * only one; for example, this
-   * would happen if both top and
-   * front faces of the left cell
-   * belong to the boundary
-   * selected whereas only the top
-   * face of the right cell belongs
-   * to it. This case is not
-   * currently implemented.
+   * Here, we get four different normal vectors, one from each of the four
+   * faces that meet at the vertex. Even though they may form a complete set
+   * of vectors, it is not our intent to constrain all components of the
+   * vector field at this point. Rather, we would like to still allow
+   * tangential flow, where the term "tangential" has to be suitably defined.
+   *
+   * In a case like this, the algorithm proceeds as follows: for each cell
+   * that has computed two tangential vectors at this point, we compute the
+   * unconstrained direction as the outer product of the two tangential
+   * vectors (if necessary multiplied by minus one). We then average these
+   * tangential vectors. Finally, we compute constraints for the two
+   * directions perpendicular to this averaged tangential direction.
+   *
+   * There are cases where one cell contributes two tangential directions and
+   * another one only one; for example, this would happen if both top and
+   * front faces of the left cell belong to the boundary selected whereas only
+   * the top face of the right cell belongs to it. This case is not currently
+   * implemented.
    *
    *
    * <h4>Results</h4>
    *
-   * Because it makes for good
-   * pictures, here are two images
-   * of vector fields on a circle
-   * and on a sphere to which the
-   * constraints computed by this
+   * Because it makes for good pictures, here are two images of vector fields
+   * on a circle and on a sphere to which the constraints computed by this
    * function have been applied:
    *
    * <p ALIGN="center">
@@ -1705,16 +1578,10 @@ namespace VectorTools
    * @image html no_normal_flux_6.png
    * </p>
    *
-   * The vectors fields are not
-   * physically reasonable but the
-   * tangentiality constraint is
-   * clearly enforced. The fact
-   * that the vector fields are
-   * zero at some points on the
-   * boundary is an artifact of the
-   * way it is created, it is not
-   * constrained to be zero at
-   * these points.
+   * The vectors fields are not physically reasonable but the tangentiality
+   * constraint is clearly enforced. The fact that the vector fields are zero
+   * at some points on the boundary is an artifact of the way it is created,
+   * it is not constrained to be zero at these points.
    *
    * @ingroup constraints
    *
@@ -1728,6 +1595,22 @@ namespace VectorTools
                                       ConstraintMatrix      &constraints,
                                       const Mapping<dim, spacedim>    &mapping = StaticMappingQ1<dim>::mapping);
 
+  /**
+   * Compute the constraints that correspond to boundary conditions of the
+   * form $\vec n \times \vec u=0$, i.e. flow normal to the boundary if $\vec
+   * u$ is a vector-valued quantity. This function constrains exactly those
+   * vector-valued components that are left unconstrained by
+   * compute_no_normal_flux_constraints, and leaves the one component
+   * unconstrained that is constrained by compute_no_normal_flux_constraints.
+   */
+  template <int dim, template <int, int> class DH, int spacedim>
+  void
+  compute_normal_flux_constraints (const DH<dim,spacedim>         &dof_handler,
+                                   const unsigned int     first_vector_component,
+                                   const std::set<types::boundary_id> &boundary_ids,
+                                   ConstraintMatrix      &constraints,
+                                   const Mapping<dim, spacedim>    &mapping = StaticMappingQ1<dim>::mapping);
+
 
   //@}
   /**
@@ -2418,11 +2301,6 @@ namespace VectorTools
    * Exception
    */
   DeclException0 (ExcNonInterpolatingFE);
-
-  /**
-   * Exception
-   */
-  DeclException0 (ExcNoComponentSelected);
 }
 
 
index a501795529cad3c48013046778d7c57813297ebf..39b16c8cf12a5a22346c9cf4dad6fab8555cc31e 100644 (file)
@@ -60,6 +60,7 @@
 #include <deal.II/numerics/vector_tools.h>
 #include <deal.II/numerics/matrix_tools.h>
 
+#include <deal.II/base/std_cxx1x/array.h>
 #include <numeric>
 #include <algorithm>
 #include <vector>
@@ -1180,36 +1181,6 @@ namespace VectorTools
 
 
 
-// separate implementation for 1D because otherwise we get linker errors since
-// FEFaceValues<1> is not compiled
-  template <>
-  void
-  create_boundary_right_hand_side (const Mapping<1,1> &,
-                                   const DoFHandler<1,1> &,
-                                   const Quadrature<0> &,
-                                   const Function<1> &,
-                                   Vector<double> &,
-                                   const std::set<types::boundary_id> &)
-  {
-    Assert (false, ExcImpossibleInDim(1));
-  }
-
-
-
-  template <>
-  void
-  create_boundary_right_hand_side (const Mapping<1,2> &,
-                                   const DoFHandler<1,2> &,
-                                   const Quadrature<0> &,
-                                   const Function<2> &,
-                                   Vector<double> &,
-                                   const std::set<types::boundary_id> &)
-  {
-    Assert (false, ExcImpossibleInDim(1));
-  }
-
-
-
   template <int dim, int spacedim>
   void
   create_boundary_right_hand_side (const Mapping<dim, spacedim>      &mapping,
@@ -1349,36 +1320,6 @@ namespace VectorTools
 
 
 
-// separate implementation for 1D because otherwise we get linker errors since
-// hp::FEFaceValues<1> is not compiled
-  template <>
-  void
-  create_boundary_right_hand_side (const hp::MappingCollection<1,1> &,
-                                   const hp::DoFHandler<1,1> &,
-                                   const hp::QCollection<0> &,
-                                   const Function<1> &,
-                                   Vector<double> &,
-                                   const std::set<types::boundary_id> &)
-  {
-    Assert (false, ExcImpossibleInDim(1));
-  }
-
-
-
-  template <>
-  void
-  create_boundary_right_hand_side (const hp::MappingCollection<1,2> &,
-                                   const hp::DoFHandler<1,2> &,
-                                   const hp::QCollection<0> &,
-                                   const Function<2> &,
-                                   Vector<double> &,
-                                   const std::set<types::boundary_id> &)
-  {
-    Assert (false, ExcImpossibleInDim(1));
-  }
-
-
-
   template <int dim, int spacedim>
   void
   create_boundary_right_hand_side (const hp::MappingCollection<dim,spacedim> &mapping,
@@ -1584,7 +1525,7 @@ namespace VectorTools
                                            boundary_function.n_components));
 
               Assert (component_mask.n_selected_components(fe.n_components()) > 0,
-                      ExcNoComponentSelected());
+                      ComponentMask::ExcNoComponentSelected());
 
               // now set the value of
               // the vertex degree of
@@ -3243,19 +3184,10 @@ namespace VectorTools
                   }
             }
 
-          // Create the system
-          // matrix by
-          // multiplying the
-          // assembling matrix
-          // with its transposed
-          // and the right
-          // hand side vector
-          // by mutliplying
-          // the assembling
-          // matrix with the
-          // assembling vector.
-          // Invert the system
-          // matrix.
+          // Create the system matrix by multiplying the assembling matrix
+          // with its transposed and the right hand side vector by mutliplying
+          // the assembling matrix with the assembling vector.  Invert the
+          // system matrix.
           assembling_matrix.mTmult (cell_matrix, assembling_matrix);
           cell_matrix_inv.invert (cell_matrix);
           assembling_matrix.vmult (cell_rhs, assembling_vector);
@@ -3285,12 +3217,8 @@ namespace VectorTools
                 }
           }
 
-          // Now we do the
-          // same as above
-          // with the vertical
-          // shape functions
-          // instead of the
-          // horizontal ones.
+          // Now we do the same as above with the vertical shape functions
+          // instead of the horizontal ones.
           for (unsigned int q_point = 0;
                q_point < fe_values.n_quadrature_points; ++q_point)
             {
@@ -3395,32 +3323,18 @@ namespace VectorTools
                                            ConstraintMatrix &constraints,
                                            const Mapping<dim> &mapping)
   {
-    // Projection-based interpolation
-    // is performed in two (in 2D)
-    // respectively three (in 3D)
-    // steps. First the tangential
-    // component of the function is
-    // interpolated on each edge.  This
-    // gives the values for the degrees
-    // of freedom corresponding to the
-    // edge shape functions. Now we are
-    // done for 2D, but in 3D we possibly
-    // have also degrees of freedom, which
-    // are located in the interior of
-    // the faces. Therefore we compute
-    // the residual of the function
-    // describing the boundary values
-    // and the interpolated part, which
-    // we have computed in the last
-    // step. On the faces there are
-    // two kinds of shape functions,
-    // the horizontal and the vertical
-    // ones. Thus we have to solve two
-    // linear systems of equations of
-    // size <tt>degree * (degree +
-    // 1)<tt> to obtain the values for
-    // the  corresponding degrees of
-    // freedom.
+    // Projection-based interpolation is performed in two (in 2D) respectively
+    // three (in 3D) steps. First the tangential component of the function is
+    // interpolated on each edge.  This gives the values for the degrees of
+    // freedom corresponding to the edge shape functions. Now we are done for
+    // 2D, but in 3D we possibly have also degrees of freedom, which are
+    // located in the interior of the faces. Therefore we compute the residual
+    // of the function describing the boundary values and the interpolated
+    // part, which we have computed in the last step. On the faces there are
+    // two kinds of shape functions, the horizontal and the vertical
+    // ones. Thus we have to solve two linear systems of equations of size
+    // <tt>degree * (degree + 1)<tt> to obtain the values for the
+    // corresponding degrees of freedom.
     const unsigned int superdegree = dof_handler.get_fe ().degree;
     const QGauss<dim - 1> reference_face_quadrature (2 * superdegree);
     const unsigned int dofs_per_face = dof_handler.get_fe ().dofs_per_face;
@@ -3663,19 +3577,12 @@ namespace VectorTools
             for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell; ++face)
               if (cell->face (face)->boundary_indicator () == boundary_component)
                 {
-                  // if the FE is a
-                  // FE_Nothing object
-                  // there is no work to
-                  // do
+                  // if the FE is a FE_Nothing object there is no work to do
                   if (dynamic_cast<const FE_Nothing<dim>*> (&cell->get_fe ()) != 0)
                     return;
 
-                  // This is only
-                  // implemented, if the
-                  // FE is a Nedelec
-                  // element. If the FE is
-                  // a FESystem we cannot
-                  // check this.
+                  // This is only implemented, if the FE is a Nedelec
+                  // element. If the FE is a FESystem we cannot check this.
                   if (dynamic_cast<const FESystem<dim>*> (&cell->get_fe ()) == 0)
                     {
                       typedef FiniteElement<dim> FEL;
@@ -3749,19 +3656,12 @@ namespace VectorTools
             for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell; ++face)
               if (cell->face (face)->boundary_indicator () == boundary_component)
                 {
-                  // if the FE is a
-                  // FE_Nothing object
-                  // there is no work to
-                  // do
+                  // if the FE is a FE_Nothing object there is no work to do
                   if (dynamic_cast<const FE_Nothing<dim>*> (&cell->get_fe ()) != 0)
                     return;
 
-                  // This is only
-                  // implemented, if the
-                  // FE is a Nedelec
-                  // element. If the FE is
-                  // a FESystem we cannot
-                  // check this.
+                  // This is only implemented, if the FE is a Nedelec
+                  // element. If the FE is a FESystem we cannot check this.
                   if (dynamic_cast<const FESystem<dim>*> (&cell->get_fe ()) == 0)
                     {
                       typedef FiniteElement<dim> FEL;
@@ -3791,11 +3691,8 @@ namespace VectorTools
                                                first_vector_component,
                                                dof_values, dofs_processed);
 
-                  // If there are higher
-                  // order shape
-                  // functions, there is
-                  // still some work
-                  // left.
+                  // If there are higher order shape functions, there is still
+                  // some work left.
                   if (degree > 0)
                     internals
                     ::compute_face_projection_curl_conforming (cell, face, fe_face_values,
@@ -3832,10 +3729,8 @@ namespace VectorTools
 
   namespace internals
   {
-    // This function computes the
-    // projection of the boundary
-    // function on the boundary
-    // in 2d.
+    // This function computes the projection of the boundary function on the
+    // boundary in 2d.
     template <typename cell_iterator>
     void
     compute_face_projection_div_conforming (const cell_iterator &cell,
@@ -3846,13 +3741,9 @@ namespace VectorTools
                                             const std::vector<DerivativeForm<1,2,2> > &jacobians,
                                             ConstraintMatrix &constraints)
     {
-      // Compute the intergral over
-      // the product of the normal
-      // components of the boundary
-      // function times the normal
-      // components of the shape
-      // functions supported on the
-      // boundary.
+      // Compute the intergral over the product of the normal components of
+      // the boundary function times the normal components of the shape
+      // functions supported on the boundary.
       const FEValuesExtractors::Vector vec (first_vector_component);
       const FiniteElement<2> &fe = cell->get_fe ();
       const std::vector<Point<2> > &normals = fe_values.get_normal_vectors ();
@@ -3862,9 +3753,7 @@ namespace VectorTools
       values (fe_values.n_quadrature_points, Vector<double> (2));
       Vector<double> dof_values (fe.dofs_per_face);
 
-      // Get the values of the
-      // boundary function at the
-      // quadrature points.
+      // Get the values of the boundary function at the quadrature points.
       {
         const std::vector<Point<2> > &
         quadrature_points = fe_values.get_quadrature_points ();
@@ -3894,10 +3783,8 @@ namespace VectorTools
 
       cell->face (face)->get_dof_indices (face_dof_indices, cell->active_fe_index ());
 
-      // Copy the computed values
-      // in the ConstraintMatrix only,
-      // if the degree of freedom is
-      // not already constrained.
+      // Copy the computed values in the ConstraintMatrix only, if the degree
+      // of freedom is not already constrained.
       for (unsigned int i = 0; i < fe.dofs_per_face; ++i)
         if (!(constraints.is_constrained (face_dof_indices[i])))
           {
@@ -3908,9 +3795,7 @@ namespace VectorTools
           }
     }
 
-    // dummy implementation of above
-    // function for all other
-    // dimensions
+    // dummy implementation of above function for all other dimensions
     template<int dim, typename cell_iterator>
     void
     compute_face_projection_div_conforming (const cell_iterator &,
@@ -3924,10 +3809,8 @@ namespace VectorTools
       Assert (false, ExcNotImplemented ());
     }
 
-    // This function computes the
-    // projection of the boundary
-    // function on the boundary
-    // in 3d.
+    // This function computes the projection of the boundary function on the
+    // boundary in 3d.
     template<typename cell_iterator>
     void
     compute_face_projection_div_conforming (const cell_iterator &cell,
@@ -3939,13 +3822,9 @@ namespace VectorTools
                                             std::vector<double> &dof_values,
                                             std::vector<types::global_dof_index> &projected_dofs)
     {
-      // Compute the intergral over
-      // the product of the normal
-      // components of the boundary
-      // function times the normal
-      // components of the shape
-      // functions supported on the
-      // boundary.
+      // Compute the intergral over the product of the normal components of
+      // the boundary function times the normal components of the shape
+      // functions supported on the boundary.
       const FEValuesExtractors::Vector vec (first_vector_component);
       const FiniteElement<3> &fe = cell->get_fe ();
       const std::vector<Point<3> > &normals = fe_values.get_normal_vectors ();
@@ -4771,12 +4650,452 @@ namespace VectorTools
 
 
 
+  namespace
+  {
+    template <int dim>
+    struct PointComparator
+    {
+      bool operator ()(const std_cxx1x::array<types::global_dof_index,dim> &p1,
+                       const std_cxx1x::array<types::global_dof_index,dim> &p2)
+      {
+        for (unsigned int d=0; d<dim; ++d)
+          if (p1[d] < p2[d])
+            return true;
+        return false;
+      }
+    };
+  }
+
+
+
+  template <int dim, template <int, int> class DH, int spacedim>
+  void
+  compute_normal_flux_constraints (const DH<dim,spacedim>&dof_handler,
+                                   const unsigned int     first_vector_component,
+                                   const std::set<types::boundary_id> &boundary_ids,
+                                   ConstraintMatrix      &constraints,
+                                   const Mapping<dim, spacedim> &mapping)
+  {
+    ConstraintMatrix no_normal_flux_constraints(constraints.get_local_lines());
+    compute_no_normal_flux_constraints (dof_handler,
+                                        first_vector_component,
+                                        boundary_ids,
+                                        no_normal_flux_constraints,
+                                        mapping);
+
+    // Extract a list that collects all vector components that belong to the
+    // same node (scalar basis function). When creating that list, we use an
+    // array of dim components that stores the global degree of freedom.
+    std::set<std_cxx1x::array<types::global_dof_index,dim>, PointComparator<dim> > vector_dofs;
+    std::vector<types::global_dof_index> face_dofs;
+
+    std::vector<std_cxx1x::array<types::global_dof_index,dim> > cell_vector_dofs;
+    for (typename DH<dim,spacedim>::active_cell_iterator cell =
+           dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
+      if (!cell->is_artificial())
+        for (unsigned int face_no=0; face_no < GeometryInfo<dim>::faces_per_cell;
+             ++face_no)
+          if (boundary_ids.find(cell->face(face_no)->boundary_indicator())
+              != boundary_ids.end())
+            {
+              const FiniteElement<dim> &fe = cell->get_fe();
+              typename DH<dim,spacedim>::face_iterator face=cell->face(face_no);
+
+              // get the indices of the dofs on this cell...
+              face_dofs.resize (fe.dofs_per_face);
+              face->get_dof_indices (face_dofs, cell->active_fe_index());
+
+              unsigned int n_scalar_indices = 0;
+              cell_vector_dofs.resize(fe.dofs_per_face);
+              for (unsigned int i=0; i<fe.dofs_per_face; ++i)
+                if (fe.face_system_to_component_index(i).first >= first_vector_component &&
+                    fe.face_system_to_component_index(i).first < first_vector_component + dim)
+                  {
+                    n_scalar_indices =
+                      std::max(n_scalar_indices,
+                               fe.face_system_to_component_index(i).second+1);
+                    cell_vector_dofs[fe.face_system_to_component_index(i).second]
+                      [fe.face_system_to_component_index(i).first-first_vector_component]
+                      = face_dofs[i];
+                  }
+
+              // now we identified the vector indices on the cell, so next
+              // insert them into the set (it would be expensive to directly
+              // insert incomplete points into the set)
+              for (unsigned int i=0; i<n_scalar_indices; ++i)
+                vector_dofs.insert(cell_vector_dofs[i]);
+            }
+
+    // iterate over the list of all vector components we found and see if we
+    // can find constrained ones
+    unsigned int n_total_constraints_found = 0;
+    for (typename std::set<std_cxx1x::array<unsigned int,dim>,PointComparator<dim> >::
+           const_iterator it=vector_dofs.begin(); it!=vector_dofs.end(); ++it)
+      {
+        unsigned int n_constraints = 0;
+        bool is_constrained[dim];
+        for (unsigned int d=0; d<dim; ++d)
+          if (no_normal_flux_constraints.is_constrained((*it)[d]))
+            {
+              is_constrained[d] = true;
+              ++n_constraints;
+              ++n_total_constraints_found;
+            }
+          else
+            is_constrained[d] = false;
+        if (n_constraints > 0)
+          {
+            // if more than one no-flux constraint is present, we need to
+            // constrain all vector degrees of freedom (we are in a corner
+            // where several faces meet and to get a continuous FE solution we
+            // need to set all conditions to zero).
+            if (n_constraints > 1)
+              {
+                for (unsigned int d=0; d<dim; ++d)
+                  constraints.add_line((*it)[d]);
+                continue;
+              }
+
+            // ok, this is a no-flux constraint, so get the index of the dof
+            // that is currently constrained and make it unconstrained. The
+            // constraint indices will get the normal that contain the other
+            // indices.
+            Tensor<1,dim> normal;
+            unsigned constrained_index = -1;
+            for (unsigned int d=0; d<dim; ++d)
+              if (is_constrained[d])
+                {
+                  constrained_index = d;
+                  normal[d] = 1.;
+                }
+            AssertIndexRange(constrained_index, dim);
+            const std::vector<std::pair<unsigned int, double> >* constrained
+              = no_normal_flux_constraints.get_constraint_entries((*it)[constrained_index]);
+            // find components to which this index is constrained to
+            Assert(constrained != 0, ExcInternalError());
+            Assert(constrained->size() < dim, ExcInternalError());
+            for (unsigned int c=0; c<constrained->size(); ++c)
+              {
+                int index = -1;
+                for (unsigned int d=0; d<dim; ++d)
+                  if ((*constrained)[c].first == (*it)[d])
+                    index = d;
+                Assert (index != -1, ExcInternalError());
+                normal[index] = (*constrained)[c].second;
+              }
+            for (unsigned int d=0; d<dim; ++d)
+              {
+                if (is_constrained[d])
+                  continue;
+                const unsigned int new_index = (*it)[d];
+                if (!constraints.is_constrained(new_index))
+                  {
+                    constraints.add_line(new_index);
+                    if (std::abs(normal[d]) > 1e-13)
+                      constraints.add_entry(new_index, (*it)[constrained_index],
+                                            -normal[d]);
+                  }
+              }
+          }
+      }
+    AssertDimension(n_total_constraints_found,
+                    no_normal_flux_constraints.n_constraints());
+  }
+
+
+
   namespace internal
   {
+    template <int dim, int spacedim>
+    struct IDScratchData
+    {
+      IDScratchData (const dealii::hp::MappingCollection<dim,spacedim> &mapping,
+                     const dealii::hp::FECollection<dim,spacedim> &fe,
+                     const dealii::hp::QCollection<dim> &q,
+                     const UpdateFlags update_flags);
+
+      IDScratchData (const IDScratchData &data);
+
+      void resize_vectors (const unsigned int n_q_points,
+                           const unsigned int n_components);
+
+      std::vector<dealii::Vector<double> > function_values;
+      std::vector<std::vector<Tensor<1,spacedim> > > function_grads;
+      std::vector<double> weight_values;
+      std::vector<dealii::Vector<double> > weight_vectors;
+
+      std::vector<dealii::Vector<double> > psi_values;
+      std::vector<std::vector<Tensor<1,spacedim> > > psi_grads;
+      std::vector<double> psi_scalar;
+
+      std::vector<double>         tmp_values;
+      std::vector<Tensor<1,spacedim> > tmp_gradients;
+
+      dealii::hp::FEValues<dim,spacedim> x_fe_values;
+    };
+
+
+    template <int dim, int spacedim>
+    IDScratchData<dim,spacedim>
+    ::IDScratchData(const dealii::hp::MappingCollection<dim,spacedim> &mapping,
+                    const dealii::hp::FECollection<dim,spacedim> &fe,
+                    const dealii::hp::QCollection<dim> &q,
+                    const UpdateFlags update_flags)
+      :
+      x_fe_values(mapping, fe, q, update_flags)
+    {}
+
+    template <int dim, int spacedim>
+    IDScratchData<dim,spacedim>::IDScratchData (const IDScratchData &data)
+      :
+      x_fe_values(data.x_fe_values.get_mapping_collection(),
+                  data.x_fe_values.get_fe_collection(),
+                  data.x_fe_values.get_quadrature_collection(),
+                  data.x_fe_values.get_update_flags())
+    {}
+
+    template <int dim, int spacedim>
+    void
+    IDScratchData<dim,spacedim>::resize_vectors (const unsigned int n_q_points,
+                                                 const unsigned int n_components)
+    {
+      function_values.resize (n_q_points,
+                              dealii::Vector<double>(n_components));
+      function_grads.resize (n_q_points,
+                             std::vector<Tensor<1,spacedim> >(n_components));
+
+      weight_values.resize (n_q_points);
+      weight_vectors.resize (n_q_points,
+                             dealii::Vector<double>(n_components));
+
+      psi_values.resize (n_q_points,
+                         dealii::Vector<double>(n_components));
+      psi_grads.resize (n_q_points,
+                        std::vector<Tensor<1,spacedim> >(n_components));
+      psi_scalar.resize (n_q_points);
+
+      tmp_values.resize (n_q_points);
+      tmp_gradients.resize (n_q_points);
+    }
+
+
+    // avoid compiling inner function for many vector types when we always
+    // really do the same thing by putting the main work into this helper
+    // function
+    template <int dim, int spacedim>
+    double
+    integrate_difference_inner (const Function<spacedim>   &exact_solution,
+                                const NormType              &norm,
+                                const Function<spacedim>    *weight,
+                                const UpdateFlags            update_flags,
+                                const double                 exponent,
+                                const unsigned int           n_components,
+                                IDScratchData<dim,spacedim> &data)
+    {
+      const bool fe_is_system = (n_components != 1);
+      const dealii::FEValues<dim, spacedim> &fe_values  = data.x_fe_values.get_present_fe_values ();
+      const unsigned int n_q_points = fe_values.n_quadrature_points;
+
+      if (weight!=0)
+        {
+          if (weight->n_components>1)
+            weight->vector_value_list (fe_values.get_quadrature_points(),
+                                       data.weight_vectors);
+          else
+            {
+              weight->value_list (fe_values.get_quadrature_points(),
+                                  data.weight_values);
+              for (unsigned int k=0; k<n_q_points; ++k)
+                data.weight_vectors[k] = data.weight_values[k];
+            }
+        }
+      else
+        {
+          for (unsigned int k=0; k<n_q_points; ++k)
+            data.weight_vectors[k] = 1.;
+        }
+
+
+      if (update_flags & update_values)
+        {
+          // first compute the exact solution (vectors) at the quadrature
+          // points try to do this as efficient as possible by avoiding a
+          // second virtual function call in case the function really has only
+          // one component
+          if (fe_is_system)
+            exact_solution.vector_value_list (fe_values.get_quadrature_points(),
+                                              data.psi_values);
+          else
+            {
+              exact_solution.value_list (fe_values.get_quadrature_points(),
+                                         data.tmp_values);
+              for (unsigned int i=0; i<n_q_points; ++i)
+                data.psi_values[i](0) = data.tmp_values[i];
+            }
+
+          // then subtract finite element fe_function
+          for (unsigned int q=0; q<n_q_points; ++q)
+            data.psi_values[q] -= data.function_values[q];
+        }
+
+      // Do the same for gradients, if required
+      if (update_flags & update_gradients)
+        {
+          // try to be a little clever to avoid recursive virtual function
+          // calls when calling gradient_list for functions that are really
+          // scalar functions
+          if (fe_is_system)
+            exact_solution.vector_gradient_list (fe_values.get_quadrature_points(),
+                                                 data.psi_grads);
+          else
+            {
+              exact_solution.gradient_list (fe_values.get_quadrature_points(),
+                                            data.tmp_gradients);
+              for (unsigned int i=0; i<n_q_points; ++i)
+                data.psi_grads[i][0] = data.tmp_gradients[i];
+            }
+
+          // then subtract finite element function_grads. We need to be
+          // careful in the codimension one case, since there we only have
+          // tangential gradients in the finite element function, not the full
+          // gradient. This is taken care of, by subtracting the normal
+          // component of the gradient from the exact function.
+          if (update_flags & update_normal_vectors)
+            for (unsigned int k=0; k<n_components; ++k)
+              for (unsigned int q=0; q<n_q_points; ++q)
+                data.psi_grads[q][k] -= (data.function_grads[q][k] +
+                                         (data.psi_grads[q][k]* // (f.n) n
+                                          fe_values.normal_vector(q))*
+                                         fe_values.normal_vector(q));
+          else
+            for (unsigned int k=0; k<n_components; ++k)
+              for (unsigned int q=0; q<n_q_points; ++q)
+                data.psi_grads[q][k] -= data.function_grads[q][k];
+        }
+
+      double diff = 0;
+      switch (norm)
+        {
+        case mean:
+          // Compute values in quadrature points and integrate
+          for (unsigned int q=0; q<n_q_points; ++q)
+            {
+              double sum = 0;
+              for (unsigned int k=0; k<n_components; ++k)
+                sum += data.psi_values[q](k) * data.weight_vectors[q](k);
+              diff += sum * fe_values.JxW(q);
+            }
+          break;
+
+        case Lp_norm:
+        case L1_norm:
+        case W1p_norm:
+          // Compute values in quadrature points and integrate
+          for (unsigned int q=0; q<n_q_points; ++q)
+            {
+              double sum = 0;
+              for (unsigned int k=0; k<n_components; ++k)
+                sum += std::pow(data.psi_values[q](k)*data.psi_values[q](k),
+                                exponent/2.) * data.weight_vectors[q](k);
+              diff += sum * fe_values.JxW(q);
+            }
+
+          // Compute the root only, if no derivative values are added later
+          if (!(update_flags & update_gradients))
+            diff = std::pow(diff, 1./exponent);
+          break;
+
+        case L2_norm:
+        case H1_norm:
+          // Compute values in quadrature points and integrate
+          for (unsigned int q=0; q<n_q_points; ++q)
+            {
+              double sum = 0;
+              for (unsigned int k=0; k<n_components; ++k)
+                sum += data.psi_values[q](k) * data.psi_values[q](k) *
+                  data.weight_vectors[q](k);
+              diff += sum * fe_values.JxW(q);
+            }
+          // Compute the root only, if no derivative values are added later
+          if (norm == L2_norm)
+            diff=std::sqrt(diff);
+          break;
+
+        case Linfty_norm:
+        case W1infty_norm:
+          for (unsigned int q=0; q<n_q_points; ++q)
+            for (unsigned int k=0; k<n_components; ++k)
+              diff = std::max (diff, std::abs(data.psi_values[q](k)*
+                                              data.weight_vectors[q](k)));
+          break;
+
+        case H1_seminorm:
+        case W1p_seminorm:
+        case W1infty_seminorm:
+          break;
+
+        default:
+          Assert (false, ExcNotImplemented());
+          break;
+        }
+
+      switch (norm)
+        {
+        case W1p_seminorm:
+        case W1p_norm:
+          for (unsigned int q=0; q<n_q_points; ++q)
+            {
+              double sum = 0;
+              for (unsigned int k=0; k<n_components; ++k)
+                sum += std::pow(data.psi_grads[q][k]*data.psi_grads[q][k],
+                                exponent/2.) * data.weight_vectors[q](k);
+              diff += sum * fe_values.JxW(q);
+            }
+          diff = std::pow(diff, 1./exponent);
+          break;
+
+        case H1_seminorm:
+        case H1_norm:
+          for (unsigned int q=0; q<n_q_points; ++q)
+            {
+              double sum = 0;
+              for (unsigned int k=0; k<n_components; ++k)
+                sum += (data.psi_grads[q][k] * data.psi_grads[q][k]) *
+                  data.weight_vectors[q](k);
+              diff += sum * fe_values.JxW(q);
+            }
+          diff = std::sqrt(diff);
+          break;
+
+        case W1infty_seminorm:
+        case W1infty_norm:
+          {
+            double t = 0;
+            for (unsigned int q=0; q<n_q_points; ++q)
+              for (unsigned int k=0; k<n_components; ++k)
+                for (unsigned int d=0; d<dim; ++d)
+                  t = std::max(t, std::abs(data.psi_grads[q][k][d]) *
+                               data.weight_vectors[q](k));
+
+            // then add seminorm to norm if that had previously been computed
+            diff += t;
+          }
+          break;
+        default:
+          break;
+        }
+
+      // append result of this cell to the end of the vector
+      Assert (numbers::is_finite(diff), ExcNumberNotFinite());
+      return diff;
+    }
+
+
+
     template <int dim, class InVector, class OutVector, class DH, int spacedim>
     static
     void
-    do_integrate_difference (const dealii::hp::MappingCollection<dim,spacedim>    &mapping,
+    do_integrate_difference (const dealii::hp::MappingCollection<dim,spacedim> &mapping,
                              const DH              &dof,
                              const InVector        &fe_function,
                              const Function<spacedim>   &exact_solution,
@@ -4786,13 +5105,9 @@ namespace VectorTools
                              const Function<spacedim>   *weight,
                              const double           exponent_1)
     {
-      // we mark the "exponent" parameter
-      // to this function "const" since
-      // it is strictly incoming, but we
-      // need to set it to something
-      // different later on, if
-      // necessary, so have a read-write
-      // version of it:
+      // we mark the "exponent" parameter to this function "const" since it is
+      // strictly incoming, but we need to set it to something different later
+      // on, if necessary, so have a read-write version of it:
       double exponent = exponent_1;
 
       const unsigned int        n_components = dof.get_fe().n_components();
@@ -4843,32 +5158,7 @@ namespace VectorTools
         }
 
       dealii::hp::FECollection<dim,spacedim> fe_collection (dof.get_fe());
-      dealii::hp::FEValues<dim,spacedim> x_fe_values(mapping, fe_collection, q, update_flags);
-
-      const unsigned int max_n_q_points = q.max_n_quadrature_points ();
-
-      std::vector< dealii::Vector<double> >
-      function_values (max_n_q_points, dealii::Vector<double>(n_components));
-      std::vector<std::vector<Tensor<1,spacedim> > >
-      function_grads (max_n_q_points, std::vector<Tensor<1,spacedim> >(n_components));
-
-      std::vector<double>
-      weight_values (max_n_q_points);
-      std::vector<dealii::Vector<double> >
-      weight_vectors (max_n_q_points, dealii::Vector<double>(n_components));
-
-      std::vector<dealii::Vector<double> >
-      psi_values (max_n_q_points, dealii::Vector<double>(n_components));
-      std::vector<std::vector<Tensor<1,spacedim> > >
-      psi_grads (max_n_q_points, std::vector<Tensor<1,spacedim> >(n_components));
-      std::vector<double>
-      psi_scalar (max_n_q_points);
-
-      // tmp vector when we use the
-      // Function<spacedim> functions for
-      // scalar functions
-      std::vector<double>         tmp_values (max_n_q_points);
-      std::vector<Tensor<1,spacedim> > tmp_gradients (max_n_q_points);
+      IDScratchData<dim,spacedim> data(mapping, fe_collection, q, update_flags);
 
       // loop over all cells
       typename DH::active_cell_iterator cell = dof.begin_active(),
@@ -4876,285 +5166,26 @@ namespace VectorTools
       for (unsigned int index=0; cell != endc; ++cell, ++index)
         if (cell->is_locally_owned())
           {
-            double diff=0;
             // initialize for this cell
-            x_fe_values.reinit (cell);
+            data.x_fe_values.reinit (cell);
 
-            const dealii::FEValues<dim, spacedim> &fe_values  = x_fe_values.get_present_fe_values ();
+            const dealii::FEValues<dim, spacedim> &fe_values  = data.x_fe_values.get_present_fe_values ();
             const unsigned int   n_q_points = fe_values.n_quadrature_points;
-
-            // resize all out scratch
-            // arrays to the number of
-            // quadrature points we use
-            // for the present cell
-            function_values.resize (n_q_points,
-                                    dealii::Vector<double>(n_components));
-            function_grads.resize (n_q_points,
-                                   std::vector<Tensor<1,spacedim> >(n_components));
-
-            weight_values.resize (n_q_points);
-            weight_vectors.resize (n_q_points,
-                                   dealii::Vector<double>(n_components));
-
-            psi_values.resize (n_q_points,
-                               dealii::Vector<double>(n_components));
-            psi_grads.resize (n_q_points,
-                              std::vector<Tensor<1,spacedim> >(n_components));
-            psi_scalar.resize (n_q_points);
-
-            tmp_values.resize (n_q_points);
-            tmp_gradients.resize (n_q_points);
-
-            if (weight!=0)
-              {
-                if (weight->n_components>1)
-                  weight->vector_value_list (fe_values.get_quadrature_points(),
-                                             weight_vectors);
-                else
-                  {
-                    weight->value_list (fe_values.get_quadrature_points(),
-                                        weight_values);
-                    for (unsigned int k=0; k<n_q_points; ++k)
-                      weight_vectors[k] = weight_values[k];
-                  }
-              }
-            else
-              {
-                for (unsigned int k=0; k<n_q_points; ++k)
-                  weight_vectors[k] = 1.;
-              }
-
+            data.resize_vectors (n_q_points, n_components);
 
             if (update_flags & update_values)
-              {
-                // first compute the exact solution
-                // (vectors) at the quadrature points
-                // try to do this as efficient as
-                // possible by avoiding a second
-                // virtual function call in case
-                // the function really has only
-                // one component
-                if (fe_is_system)
-                  exact_solution.vector_value_list (fe_values.get_quadrature_points(),
-                                                    psi_values);
-                else
-                  {
-                    exact_solution.value_list (fe_values.get_quadrature_points(),
-                                               tmp_values);
-                    for (unsigned int i=0; i<n_q_points; ++i)
-                      psi_values[i](0) = tmp_values[i];
-                  }
-
-                // then subtract finite element
-                // fe_function
-                fe_values.get_function_values (fe_function, function_values);
-                for (unsigned int q=0; q<n_q_points; ++q)
-                  psi_values[q] -= function_values[q];
-              }
-
-            // Do the same for gradients, if required
+              fe_values.get_function_values (fe_function, data.function_values);
             if (update_flags & update_gradients)
-              {
-                // try to be a little clever
-                // to avoid recursive virtual
-                // function calls when calling
-                // gradient_list for functions
-                // that are really scalar
-                // functions
-                if (fe_is_system)
-                  exact_solution.vector_gradient_list (fe_values.get_quadrature_points(),
-                                                       psi_grads);
-                else
-                  {
-                    exact_solution.gradient_list (fe_values.get_quadrature_points(),
-                                                  tmp_gradients);
-                    for (unsigned int i=0; i<n_q_points; ++i)
-                      psi_grads[i][0] = tmp_gradients[i];
-                  }
-
-                // then subtract finite element
-                // function_grads. We
-                // need to be careful
-                // in the codimension
-                // one case, since
-                // there we only have
-                // tangential gradients
-                // in the finite
-                // element function,
-                // not the full
-                // gradient. This is
-                // taken care of, by
-                // subtracting the
-                // normal component of
-                // the gradient from
-                // the exact function.
-                fe_values.get_function_grads (fe_function, function_grads);
-                if (update_flags & update_normal_vectors)
-                  for (unsigned int k=0; k<n_components; ++k)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      psi_grads[q][k] -= (function_grads[q][k] +
-                                          (psi_grads[q][k]* // (f.n) n
-                                           fe_values.normal_vector(q))*
-                                          fe_values.normal_vector(q));
-                else
-                  for (unsigned int k=0; k<n_components; ++k)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      psi_grads[q][k] -= function_grads[q][k];
-              }
-
-            switch (norm)
-              {
-              case mean:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                // Compute values in
-                // quadrature points
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    psi_scalar[q] += psi_values[q](k)
-                                     * weight_vectors[q](k);
-
-                // Integrate
-                diff = std::inner_product (psi_scalar.begin(), psi_scalar.end(),
-                                           fe_values.get_JxW_values().begin(),
-                                           0.0);
-                break;
-              case Lp_norm:
-              case L1_norm:
-              case W1p_norm:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                // Compute values in
-                // quadrature points
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    psi_scalar[q] += std::pow(psi_values[q](k)*psi_values[q](k),
-                                              exponent/2.)
-                                     * weight_vectors[q](k);
-
-                // Integrate
-                diff = std::inner_product (psi_scalar.begin(), psi_scalar.end(),
-                                           fe_values.get_JxW_values().begin(),
-                                           0.0);
-                // Compute the root only,
-                // if no derivative
-                // values are added later
-                if (!(update_flags & update_gradients))
-                  diff = std::pow(diff, 1./exponent);
-                break;
-              case L2_norm:
-              case H1_norm:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                // Compute values in
-                // quadrature points
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    psi_scalar[q] += psi_values[q](k)*psi_values[q](k)
-                                     * weight_vectors[q](k);
-
-                // Integrate
-                diff = std::inner_product (psi_scalar.begin(), psi_scalar.end(),
-                                           fe_values.get_JxW_values().begin(),
-                                           0.0);
-                // Compute the root only,
-                // if no derivative
-                // values are added later
-                if (norm == L2_norm)
-                  diff=std::sqrt(diff);
-                break;
-              case Linfty_norm:
-              case W1infty_norm:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    {
-                      double newval = std::fabs(psi_values[q](k))
-                                      * weight_vectors[q](k);
-                      if (psi_scalar[q]<newval)
-                        psi_scalar[q] = newval;
-                    }
-                // Maximum on one cell
-                diff = *std::max_element (psi_scalar.begin(), psi_scalar.end());
-                break;
-              case H1_seminorm:
-              case W1p_seminorm:
-              case W1infty_seminorm:
-                break;
-              default:
-                Assert (false, ExcNotImplemented());
-                break;
-              }
+              fe_values.get_function_grads (fe_function, data.function_grads);
 
-            switch (norm)
-              {
-              case W1p_seminorm:
-              case W1p_norm:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    psi_scalar[q] += std::pow(psi_grads[q][k] * psi_grads[q][k],
-                                              exponent/2.)
-                                     * weight_vectors[q](k);
-
-                diff += std::inner_product (psi_scalar.begin(), psi_scalar.end(),
-                                            fe_values.get_JxW_values().begin(),
-                                            0.0);
-                diff = std::pow(diff, 1./exponent);
-                break;
-              case H1_seminorm:
-              case H1_norm:
-                // take square of integrand
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    psi_scalar[q] += (psi_grads[q][k] * psi_grads[q][k])
-                                     * weight_vectors[q](k);
-
-                // add seminorm to L_2 norm or
-                // to zero
-                diff += std::inner_product (psi_scalar.begin(), psi_scalar.end(),
-                                            fe_values.get_JxW_values().begin(),
-                                            0.0);
-                diff = std::sqrt(diff);
-                break;
-
-              case W1infty_seminorm:
-              case W1infty_norm:
-                std::fill_n (psi_scalar.begin(), n_q_points, 0.0);
-                for (unsigned int k=0; k<n_components; ++k)
-                  for (unsigned int q=0; q<n_q_points; ++q)
-                    {
-                      double t = 0.;
-                      for (unsigned int d=0; d<dim; ++d)
-                        t = std::max(t,std::fabs(psi_grads[q][k][d])
-                                     * weight_vectors[q](k));
-
-                      psi_scalar[q] = std::max(psi_scalar[q],t);
-                    }
-
-                // compute seminorm
-                {
-                  double t = 0;
-                  for (unsigned int i=0; i<psi_scalar.size(); ++i)
-                    t = std::max (t, psi_scalar[i]);
-
-                  // then add seminorm to norm if that had previously been
-                  // computed
-                  diff += t;
-                }
-                break;
-              default:
-                break;
-              }
-            // append result of this cell
-            // to the end of the vector
-            Assert (numbers::is_finite(diff), ExcNumberNotFinite());
-            difference(index) = diff;
+            difference(index) =
+              integrate_difference_inner (exact_solution, norm, weight,
+                                          update_flags, exponent,
+                                          n_components, data);
           }
         else
-          // the cell is a ghost cell
-          // or is artificial. write
-          // a zero into the
-          // corresponding value of
-          // the returned vector
+          // the cell is a ghost cell or is artificial. write a zero into the
+          // corresponding value of the returned vector
           difference(index) = 0;
     }
 
@@ -5235,7 +5266,7 @@ namespace VectorTools
                         const double              exponent)
   {
     internal
-    ::do_integrate_difference(hp::StaticMappingQ1<dim>::mapping_collection,
+    ::do_integrate_difference(hp::StaticMappingQ1<dim,spacedim>::mapping_collection,
                               dof, fe_function, exact_solution,
                               difference, q,
                               norm, weight, exponent);
@@ -5544,7 +5575,7 @@ namespace VectorTools
             }
         // Error out if we have not constrained anything. Note that in this
         // case the vector v is always nonempty.
-        Assert (n == 0 || counter > 0, ExcNoComponentSelected());
+        Assert (n == 0 || counter > 0, ComponentMask::ExcNoComponentSelected());
 
         s /= counter;
 
index 96c55ff3db97a9774b5796a2ac07f6eda84f7542..bab0c9796ee1bd338f8534ff0a310d9ee4ae761e 100644 (file)
@@ -85,8 +85,8 @@ FOREACH(build ${DEAL_II_BUILD_TYPES})
     )
 
   TARGET_LINK_LIBRARIES(${DEAL_II_BASE_NAME}${DEAL_II_${build}_SUFFIX}
-    ${DEAL_II_EXTERNAL_LIBRARIES}
     ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
+    ${DEAL_II_EXTERNAL_LIBRARIES}
     )
 
   INSTALL(TARGETS ${DEAL_II_BASE_NAME}${DEAL_II_${build}_SUFFIX}
index 7277a8520d25fbe043e5c45de8b733b55019579b..b285026281f3e4b02f70a2095d3c05481f13450e 100644 (file)
@@ -2228,13 +2228,16 @@ DataOutBase::SvgFlags::SvgFlags (const unsigned int height_vector,
                                  const int polar_angle,
                                  const unsigned int line_thickness,
                                  const bool margin,
-                                 const bool draw_colorbar) :
-  height_vector(height_vector),
-  azimuth_angle(azimuth_angle),
-  polar_angle(polar_angle),
-  line_thickness(line_thickness),
-  margin(margin),
-  draw_colorbar(draw_colorbar)
+                                 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)
 {}
 
 
@@ -5611,8 +5614,8 @@ void DataOutBase::write_svg (const std::vector<Patch<dim,spacedim> > &patches,
   // do not allow volume rendering
   AssertThrow (dim==2, ExcNotImplemented());
 
-  const unsigned int height = 4000;
-  unsigned int width;
+  const unsigned int height = flags.height;
+  unsigned int width = flags.width;
 
   // margin around the plotted area
   unsigned int margin_in_percent = 0;
@@ -5932,10 +5935,11 @@ void DataOutBase::write_svg (const std::vector<Patch<dim,spacedim> > &patches,
             }
         }
     }
-
+  
 
 // write the svg file
-  width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
+  if (width==0)
+    width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
   unsigned int additional_width = 0;
 
   if (flags.draw_colorbar) additional_width = static_cast<unsigned int>(.5 + height * .3); // additional width for colorbar
@@ -6494,7 +6498,7 @@ void DataOutInterface<dim,spacedim>::write_vtu_in_parallel (const char *filename
   MPI_Info info;
   MPI_Info_create(&info);
   MPI_File fh;
-  MPI_File_open(MPI_COMM_WORLD, const_cast<char *>(filename),
+  MPI_File_open(comm, const_cast<char *>(filename),
                 MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &fh);
   MPI_File_set_size(fh, 0); // delete the file contents
   // this barrier is necessary, because otherwise others might already
index 6a8c426d4e86bbdbebcd228a45499f102bd5efcb..eb0bde28f45b8d661be72d408783c69407154bed 100644 (file)
@@ -433,14 +433,18 @@ namespace Patterns
 
   List::List (const PatternBase  &p,
               const unsigned int  min_elements,
-              const unsigned int  max_elements)
+              const unsigned int  max_elements,
+              const std::string  &separator)
     :
     pattern (p.clone()),
     min_elements (min_elements),
-    max_elements (max_elements)
+    max_elements (max_elements),
+    separator (separator)
   {
     Assert (min_elements <= max_elements,
             ExcInvalidRange (min_elements, max_elements));
+    Assert (separator.size() > 0,
+            ExcMessage ("The separator must have a non-zero length."));
   }
 
 
@@ -457,7 +461,6 @@ namespace Patterns
   {
     std::string tmp = test_string_list;
     std::vector<std::string> split_list;
-    split_list.reserve (std::count (tmp.begin(), tmp.end(), ',')+1);
 
     // first split the input list
     while (tmp.length() != 0)
@@ -465,10 +468,10 @@ namespace Patterns
         std::string name;
         name = tmp;
 
-        if (name.find(",") != std::string::npos)
+        if (name.find(separator) != std::string::npos)
           {
-            name.erase (name.find(","), std::string::npos);
-            tmp.erase (0, tmp.find(",")+1);
+            name.erase (name.find(separator), std::string::npos);
+            tmp.erase (0, tmp.find(separator)+separator.size());
           }
         else
           tmp = "";
@@ -481,7 +484,7 @@ namespace Patterns
           name.erase (name.length()-1, 1);
 
         split_list.push_back (name);
-      };
+      }
 
     if ((split_list.size() < min_elements) ||
         (split_list.size() > max_elements))
@@ -506,8 +509,10 @@ namespace Patterns
     description << description_init
                 << " list of <" << pattern->description() << ">"
                 << " of length " << min_elements << "..." << max_elements
-                << " (inclusive)"
-                << "]";
+                << " (inclusive)";
+    if (separator != ",")
+      description << " separated by <" << separator << ">";
+    description << "]";
 
     return description.str();
   }
@@ -517,7 +522,7 @@ namespace Patterns
   PatternBase *
   List::clone () const
   {
-    return new List(*pattern, min_elements, max_elements);
+    return new List(*pattern, min_elements, max_elements, separator);
   }
 
 
@@ -525,7 +530,8 @@ namespace Patterns
   List::memory_consumption () const
   {
     return (sizeof(*this) +
-            MemoryConsumption::memory_consumption(*pattern));
+            MemoryConsumption::memory_consumption(*pattern) +
+            MemoryConsumption::memory_consumption(separator));
   }
 
 
@@ -552,7 +558,14 @@ namespace Patterns
         if (!(is >> max_elements))
           return new List(*base_pattern, min_elements);
 
-        return new List(*base_pattern, min_elements, max_elements);
+        is.ignore(strlen(" separated by <"));
+        std::string separator;
+        if (!is)
+          std::getline(is, separator, '>');
+        else
+          separator = ",";
+
+        return new List(*base_pattern, min_elements, max_elements, separator);
       }
     else
       return 0;
@@ -569,15 +582,22 @@ namespace Patterns
   Map::Map (const PatternBase  &p_key,
             const PatternBase  &p_value,
             const unsigned int  min_elements,
-            const unsigned int  max_elements)
+            const unsigned int  max_elements,
+            const std::string  &separator)
     :
     key_pattern (p_key.clone()),
     value_pattern (p_value.clone()),
     min_elements (min_elements),
-    max_elements (max_elements)
+    max_elements (max_elements),
+    separator (separator)
   {
     Assert (min_elements <= max_elements,
             ExcInvalidRange (min_elements, max_elements));
+    Assert (separator.size() > 0,
+            ExcMessage ("The separator must have a non-zero length."));
+    Assert (separator != ":",
+            ExcMessage ("The separator can not be a colon ':' sicne that "
+                        "is the separator between the two elements of <key:value> pairs"));
   }
 
 
@@ -597,7 +617,6 @@ namespace Patterns
   {
     std::string tmp = test_string_list;
     std::vector<std::string> split_list;
-    split_list.reserve (std::count (tmp.begin(), tmp.end(), ',')+1);
 
     // first split the input list at comma sites
     while (tmp.length() != 0)
@@ -605,10 +624,10 @@ namespace Patterns
         std::string map_entry;
         map_entry = tmp;
 
-        if (map_entry.find(",") != std::string::npos)
+        if (map_entry.find(separator) != std::string::npos)
           {
-            map_entry.erase (map_entry.find(","), std::string::npos);
-            tmp.erase (0, tmp.find(",")+1);
+            map_entry.erase (map_entry.find(separator), std::string::npos);
+            tmp.erase (0, tmp.find(separator)+separator.size());
           }
         else
           tmp = "";
@@ -621,7 +640,7 @@ namespace Patterns
           map_entry.erase (map_entry.length()-1, 1);
 
         split_list.push_back (map_entry);
-      };
+      }
 
     if ((split_list.size() < min_elements) ||
         (split_list.size() > max_elements))
@@ -669,8 +688,10 @@ namespace Patterns
                 << key_pattern->description() << ":"
                 << value_pattern->description() << ">"
                 << " of length " << min_elements << "..." << max_elements
-                << " (inclusive)"
-                << "]";
+                << " (inclusive)";
+    if (separator != ",")
+      description << " separated by <" << separator << ">";
+    description << "]";
 
     return description.str();
   }
@@ -680,7 +701,9 @@ namespace Patterns
   PatternBase *
   Map::clone () const
   {
-    return new Map(*key_pattern, *value_pattern, min_elements, max_elements);
+    return new Map(*key_pattern, *value_pattern,
+                   min_elements, max_elements,
+                   separator);
   }
 
 
@@ -689,7 +712,8 @@ namespace Patterns
   {
     return (sizeof(*this) +
             MemoryConsumption::memory_consumption (*key_pattern) +
-            MemoryConsumption::memory_consumption (*value_pattern));
+            MemoryConsumption::memory_consumption (*value_pattern) +
+            MemoryConsumption::memory_consumption (separator));
   }
 
 
@@ -724,7 +748,16 @@ namespace Patterns
         if (!(is >> max_elements))
           return new Map(*key_pattern, *value_pattern, min_elements);
 
-        return new Map(*key_pattern, *value_pattern, min_elements, max_elements);
+        is.ignore(strlen(" separated by <"));
+        std::string separator;
+        if (!is)
+          std::getline(is, separator, '>');
+        else
+          separator = ",";
+
+        return new Map(*key_pattern, *value_pattern,
+                       min_elements, max_elements,
+                       separator);
       }
     else
       return 0;
@@ -1280,7 +1313,8 @@ ParameterHandler::get_current_full_path (const std::string &name) const
 
 
 
-bool ParameterHandler::read_input (std::istream &input)
+bool ParameterHandler::read_input (std::istream &input,
+                                   const std::string &filename)
 {
   AssertThrow (input, ExcIO());
 
@@ -1292,8 +1326,7 @@ bool ParameterHandler::read_input (std::istream &input)
     {
       ++lineno;
       getline (input, line);
-      if (!scan_line (line, lineno))
-        status = false;
+      status &= scan_line (line, filename, lineno);
     }
 
   return status;
@@ -1313,7 +1346,7 @@ bool ParameterHandler::read_input (const std::string &filename,
       std::ifstream input (openname.c_str());
       AssertThrow(input, ExcIO());
 
-      return read_input (input);
+      return read_input (input, filename);
     }
   catch (const PathSearch::ExcFileNotFound &)
     {
@@ -1335,34 +1368,10 @@ bool ParameterHandler::read_input (const std::string &filename,
 
 bool ParameterHandler::read_input_from_string (const char *s)
 {
-  // if empty std::string then exit
-  // with success
-  if ((s == 0) || ((*s) == 0)) return true;
-
-  std::string line;
-  std::string input (s);
-  int    lineno=0;
-
-  // if necessary append a newline char
-  // to make all lines equal
-  if (input[input.length()-1] != '\n')
-    input += '\n';
-
-  bool status = true;
-  while (input.size() != 0)
-    {
-      // get one line from Input (=s)
-      line.assign (input, 0, input.find('\n'));
-      // delete this part including
-      // the backspace
-      input.erase (0, input.find('\n')+1);
-      ++lineno;
-
-      if (!scan_line (line, lineno))
-        status = false;
-    }
-
-  return status;
+  // create an istringstream representation and pass it off
+  // to the other functions doing this work
+  std::istringstream in (s);
+  return read_input (in, "input string");
 }
 
 
@@ -1571,6 +1580,10 @@ ParameterHandler::declare_entry (const std::string           &entry,
   entries->put (get_current_full_path(entry) + path_separator +
                 "pattern_description",
                 patterns.back()->description());
+
+  // as documented, do the default value checking at the very end
+  AssertThrow (pattern.match (default_value),
+               ExcValueDoesNotMatchPattern (default_value, pattern.description()));
 }
 
 
@@ -2242,8 +2255,9 @@ ParameterHandler::log_parameters_section (LogStream &out)
 
 
 bool
-ParameterHandler::scan_line (std::string        line,
-                             const unsigned int lineno)
+ParameterHandler::scan_line (std::string         line,
+                             const std::string  &input_filename,
+                             const unsigned int  lineno)
 {
   // if there is a comment, delete it
   if (line.find('#') != std::string::npos)
@@ -2256,11 +2270,14 @@ ParameterHandler::scan_line (std::string        line,
     line.erase (line.find("  "), 1);
   // now every existing whitespace
   // should be exactly one ' ';
-  // if at end or beginning: delete
-  if ((line.length() != 0) && (std::isspace (line[0])))  line.erase (0, 1);
+  // if at beginning: delete
+  if ((line.length() != 0) && (std::isspace (line[0])))
+    line.erase (0, 1);
   // if line is now empty: leave
-  if (line.length() == 0) return true;
+  if (line.length() == 0)
+    return true;
 
+  // also delete spaces at the end
   if (std::isspace (line[line.length()-1]))
     line.erase (line.size()-1, 1);
 
@@ -2276,8 +2293,9 @@ ParameterHandler::scan_line (std::string        line,
       // check whether subsection exists
       if (!entries->get_child_optional (get_current_full_path(subsection)))
         {
-          std::cerr << "Line " << lineno
-                    << ": There is no such subsection to be entered: "
+          std::cerr << "Line <" << lineno
+                    << "> of file <" << input_filename
+                    << ">: There is no such subsection to be entered: "
                     << demangle(get_current_full_path(subsection)) << std::endl;
           for (unsigned int i=0; i<subsection_path.size(); ++i)
             std::cerr << std::setw(i*2+4) << " "
@@ -2298,8 +2316,9 @@ ParameterHandler::scan_line (std::string        line,
     {
       if (subsection_path.size() == 0)
         {
-          std::cerr << "Line " << lineno
-                    << ": There is no subsection to leave here!" << std::endl;
+          std::cerr << "Line <" << lineno
+                    << "> of file <" << input_filename
+                    << ">: There is no subsection to leave here!" << std::endl;
           return false;
         }
       else
@@ -2340,7 +2359,9 @@ ParameterHandler::scan_line (std::string        line,
                 = entries->get<unsigned int> (get_current_full_path(entry_name) + path_separator + "pattern");
               if (!patterns[pattern_index]->match(entry_value))
                 {
-                  std::cerr << "Line " << lineno << ":" << std::endl
+                  std::cerr << "Line <" << lineno
+                            << "> of file <" << input_filename
+                            << ">:" << std::endl
                             << "    The entry value" << std::endl
                             << "        " << entry_value << std::endl
                             << "    for the entry named" << std::endl
@@ -2358,8 +2379,9 @@ ParameterHandler::scan_line (std::string        line,
         }
       else
         {
-          std::cerr << "Line " << lineno
-                    << ": No such entry was declared:" << std::endl
+          std::cerr << "Line <" << lineno
+                    << "> of file <" << input_filename
+                    << ">: No such entry was declared:" << std::endl
                     << "    " << entry_name << std::endl
                     << "    <Present subsection:" << std::endl;
           for (unsigned int i=0; i<subsection_path.size(); ++i)
@@ -2371,9 +2393,46 @@ ParameterHandler::scan_line (std::string        line,
         }
     }
 
+  // an include statement?
+  if ((line.find ("INCLUDE ") == 0) ||
+      (line.find ("include ") == 0))
+    {
+      // erase "set" statement and eliminate
+      // spaces around the '='
+      line.erase (0, 7);
+      while ((line.size() > 0) && (line[0] == ' '))
+        line.erase (0, 1);
+
+      // the remainder must then be a filename
+      if (line.size() == 0)
+        {
+          std::cerr << "Line <" << lineno
+                    << "> of file <" << input_filename
+                    << "> is an include statement but does not name a file!"
+                    << std::endl;
+
+          return false;
+        }
+
+      std::ifstream input (line.c_str());
+      if (!input)
+        {
+          std::cerr << "Line <" << lineno
+                    << "> of file <" << input_filename
+                    << "> is an include statement but the file <"
+                    << line << "> could not be opened!"
+                    << std::endl;
+
+          return false;
+        }
+      else
+        return read_input (input);
+    }
+
   // this line matched nothing known
-  std::cerr << "Line " << lineno
-            << ": This line matched nothing known ('set' or 'subsection' missing!?):" << std::endl
+  std::cerr << "Line <" << lineno
+            << "> of file <" << input_filename
+            << ">: This line matched nothing known ('set' or 'subsection' missing!?):" << std::endl
             << "    " << line << std::endl;
   return false;
 }
index bd9748bc5b7bf813dad3c51a53a3414e0347b137..b800411896cba99af83f947df8181261170374a1 100644 (file)
@@ -122,10 +122,9 @@ namespace Utilities
     void
     Partitioner::set_ghost_indices (const IndexSet &ghost_indices_in)
     {
-      // Set ghost indices from input. To be sure
-      // that no entries from the locally owned
-      // range are present, subtract the locally
-      // owned indices in any case.
+      // Set ghost indices from input. To be sure that no entries from the
+      // locally owned range are present, subtract the locally owned indices
+      // in any case.
       Assert (ghost_indices_in.n_elements() == 0 ||
               ghost_indices_in.size() == locally_owned_range_data.size(),
               ExcDimensionMismatch (ghost_indices_in.size(),
@@ -137,18 +136,14 @@ namespace Utilities
       ghost_indices_data.compress();
       n_ghost_indices_data = ghost_indices_data.n_elements();
 
-      // In the rest of this function, we determine
-      // the point-to-point communication pattern of
-      // the partitioner. We make up a list with
-      // both the processors the ghost indices
-      // actually belong to, and the indices that
-      // are locally held but ghost indices of other
-      // processors. This allows then to import and
-      // export data very easily.
-
-      // find out the end index for each processor
-      // and communicate it (this implies the start
-      // index for the next processor)
+      // In the rest of this function, we determine the point-to-point
+      // communication pattern of the partitioner. We make up a list with both
+      // the processors the ghost indices actually belong to, and the indices
+      // that are locally held but ghost indices of other processors. This
+      // allows then to import and export data very easily.
+
+      // find out the end index for each processor and communicate it (this
+      // implies the start index for the next processor)
 #ifdef DEAL_II_WITH_MPI
       if (n_procs < 2)
         {
@@ -165,9 +160,8 @@ namespace Utilities
                     MPI_BYTE, communicator);
       first_index[n_procs] = global_size;
 
-      // fix case when there are some processors
-      // without any locally owned indices: then
-      // there might be a zero in some entries
+      // fix case when there are some processors without any locally owned
+      // indices: then there might be a zero in some entries
       if (global_size > 0)
         {
           unsigned int first_proc_with_nonzero_dofs = 0;
@@ -181,8 +175,7 @@ namespace Utilities
             if (first_index[i] == 0)
               first_index[i] = first_index[i-1];
 
-          // correct if our processor has a wrong local
-          // range
+          // correct if our processor has a wrong local range
           if (first_index[my_pid] != local_range_data.first)
             {
               Assert(local_range_data.first == local_range_data.second,
@@ -191,20 +184,16 @@ namespace Utilities
             }
         }
 
-      // Allocate memory for data that will be
-      // exported
+      // Allocate memory for data that will be exported
       std::vector<types::global_dof_index> expanded_ghost_indices (n_ghost_indices_data);
       unsigned int n_ghost_targets = 0;
       if (n_ghost_indices_data > 0)
         {
-          // Create first a vector of ghost_targets from
-          // the list of ghost indices and then push
-          // back new values. When we are done, copy the
-          // data to that field of the partitioner. This
-          // way, the variable ghost_targets will have
-          // exactly the size we need, whereas the
-          // vector filled with push_back might actually
-          // be too long.
+          // Create first a vector of ghost_targets from the list of ghost
+          // indices and then push back new values. When we are done, copy the
+          // data to that field of the partitioner. This way, the variable
+          // ghost_targets will have exactly the size we need, whereas the
+          // vector filled with push_back might actually be too long.
           unsigned int current_proc = 0;
           ghost_indices_data.fill_index_vector (expanded_ghost_indices);
           unsigned int current_index = expanded_ghost_indices[0];
@@ -233,8 +222,7 @@ namespace Utilities
             n_ghost_indices_data - ghost_targets_temp[n_ghost_targets-1].second;
           ghost_targets_data = ghost_targets_temp;
         }
-      // find the processes that want to import to
-      // me
+      // find the processes that want to import to me
       {
         std::vector<int> send_buffer (n_procs, 0);
         std::vector<int> receive_buffer (n_procs, 0);
@@ -257,9 +245,8 @@ namespace Utilities
         import_targets_data = import_targets_temp;
       }
 
-      // send and receive indices for import
-      // data. non-blocking receives and blocking
-      // sends
+      // send and receive indices for import data. non-blocking receives and
+      // blocking sends
       std::vector<types::global_dof_index> expanded_import_indices (n_import_indices_data);
       {
         unsigned int current_index_start = 0;
@@ -290,9 +277,8 @@ namespace Utilities
         MPI_Waitall (import_requests.size(), &import_requests[0],
                      MPI_STATUSES_IGNORE);
 
-        // transform import indices to local index
-        // space and compress contiguous indices in
-        // form of ranges
+        // transform import indices to local index space and compress
+        // contiguous indices in form of ranges
         {
           types::global_dof_index last_index = numbers::invalid_dof_index-1;
           std::vector<std::pair<types::global_dof_index,types::global_dof_index> > compressed_import_indices;
index f791bd398eaab9db171fe0ae3996ecd5d506853f..e3bf9d563148cd69c2e6ddb8dbe15af5ff90810e 100644 (file)
@@ -23,23 +23,31 @@ FILE(GLOB _header
 SET(_src
   block_info.cc
   dof_accessor.cc
+  dof_accessor_get.cc
+  dof_accessor_set.cc
   dof_faces.cc
   dof_handler.cc
   dof_handler_policy.cc
   dof_objects.cc
   dof_renumbering.cc
   dof_tools.cc
+  dof_tools_constraints.cc
+  dof_tools_sparsity.cc
   number_cache.cc
   )
 
 SET(_inst
   block_info.inst.in
   dof_accessor.inst.in
+  dof_accessor_get.inst.in
+  dof_accessor_set.inst.in
   dof_handler.inst.in
   dof_handler_policy.inst.in
   dof_objects.inst.in
   dof_renumbering.inst.in
   dof_tools.inst.in
+  dof_tools_constraints.inst.in
+  dof_tools_sparsity.inst.in
   )
 
 DEAL_II_ADD_LIBRARY(obj_dofs OBJECT ${_src} ${_header} ${_inst})
index 59b8c4833404a969bec960f284849ed4f09998a1..34dbb349064bb5dfb18fe57ecb8d7bd0e14633e4 100644 (file)
 //
 // ---------------------------------------------------------------------
 
-#include <deal.II/lac/vector.h>
-#include <deal.II/lac/block_vector.h>
-#include <deal.II/lac/parallel_vector.h>
-#include <deal.II/lac/parallel_block_vector.h>
-#include <deal.II/lac/petsc_vector.h>
-#include <deal.II/lac/petsc_block_vector.h>
-#include <deal.II/lac/trilinos_vector.h>
-#include <deal.II/lac/trilinos_block_vector.h>
-#include <deal.II/lac/sparse_matrix.h>
-
 #include <deal.II/dofs/dof_accessor.h>
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_levels.h>
@@ -97,174 +87,6 @@ DoFCellAccessor<DH,lda>::neighbor_child_on_subface (const unsigned int face,
 
 
 
-template <class DH, bool lda>
-template <class InputVector, typename number>
-void
-DoFCellAccessor<DH,lda>::
-get_interpolated_dof_values (const InputVector &values,
-                             Vector<number>    &interpolated_values) const
-{
-  const FiniteElement<dim,spacedim> &fe            = this->get_fe();
-  const unsigned int        dofs_per_cell = fe.dofs_per_cell;
-
-  Assert (this->dof_handler != 0,
-          typename BaseClass::ExcInvalidObject());
-  Assert (&fe != 0,
-          typename BaseClass::ExcInvalidObject());
-  Assert (interpolated_values.size() == dofs_per_cell,
-          typename BaseClass::ExcVectorDoesNotMatch());
-  Assert (values.size() == this->dof_handler->n_dofs(),
-          typename BaseClass::ExcVectorDoesNotMatch());
-
-  if (!this->has_children())
-    // if this cell has no children: simply
-    // return the exact values on this cell
-    this->get_dof_values (values, interpolated_values);
-  else
-    // otherwise clobber them from the children
-    {
-      Vector<number> tmp1(dofs_per_cell);
-      Vector<number> tmp2(dofs_per_cell);
-
-      interpolated_values = 0;
-
-      // later on we will have to
-      // push the values interpolated
-      // from the child to the mother
-      // cell into the output
-      // vector. unfortunately, there
-      // are two types of elements:
-      // ones where you add up the
-      // contributions from the
-      // different child cells, and
-      // ones where you overwrite.
-      //
-      // an example for the first is
-      // piecewise constant (and
-      // discontinuous) elements,
-      // where we build the value on
-      // the coarse cell by averaging
-      // the values from the cell
-      // (i.e. by adding up a
-      // fraction of the values of
-      // their values)
-      //
-      // an example for the latter
-      // are the usual continuous
-      // elements. the value on a
-      // vertex of a coarse cell must
-      // there be the same,
-      // irrespective of the adjacent
-      // cell we are presently on. so
-      // we always overwrite. in
-      // fact, we must, since we
-      // cannot know in advance how
-      // many neighbors there will
-      // be, so there is no way to
-      // compute the average with
-      // fixed factors
-      //
-      // so we have to find out to
-      // which type this element
-      // belongs. the difficulty is:
-      // the finite element may be a
-      // composed one, so we can only
-      // hope to do this for each
-      // shape function
-      // individually. in fact, there
-      // are even weird finite
-      // elements (for example the
-      // Raviart-Thomas element)
-      // which have shape functions
-      // that are additive (interior
-      // ones) and others that are
-      // overwriting (face degrees of
-      // freedom that need to be
-      // continuous across the
-      // face). to avoid checking
-      // this over and over again, we
-      // do this once now and cache
-      // the results
-      std::vector<bool> restriction_is_additive (dofs_per_cell);
-      for (unsigned int i=0; i<dofs_per_cell; ++i)
-        restriction_is_additive[i] = fe.restriction_is_additive(i);
-
-      for (unsigned int child=0; child<this->n_children(); ++child)
-        {
-          // get the values from the present
-          // child, if necessary by
-          // interpolation itself
-          this->child(child)->get_interpolated_dof_values (values,
-                                                           tmp1);
-          // interpolate these to the mother
-          // cell
-          fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
-
-          // and add up or set them
-          // in the output vector
-          for (unsigned int i=0; i<dofs_per_cell; ++i)
-            if (restriction_is_additive[i])
-              interpolated_values(i) += tmp2(i);
-            else if (tmp2(i) != number())
-              interpolated_values(i) = tmp2(i);
-        }
-    }
-}
-
-
-
-template <class DH, bool lda>
-template <class OutputVector, typename number>
-void
-DoFCellAccessor<DH,lda>::
-set_dof_values_by_interpolation (const Vector<number> &local_values,
-                                 OutputVector         &values) const
-{
-  const unsigned int dofs_per_cell = this->get_fe().dofs_per_cell;
-
-  Assert (this->dof_handler != 0,
-          typename BaseClass::ExcInvalidObject());
-  Assert (&this->get_fe() != 0,
-          typename BaseClass::ExcInvalidObject());
-  Assert (local_values.size() == dofs_per_cell,
-          typename BaseClass::ExcVectorDoesNotMatch());
-  Assert (values.size() == this->dof_handler->n_dofs(),
-          typename BaseClass::ExcVectorDoesNotMatch());
-
-  if (!this->has_children())
-    // if this cell has no children: simply
-    // set the values on this cell
-    this->set_dof_values (local_values, values);
-  else
-    // otherwise distribute them to the children
-    {
-      Vector<number> tmp(dofs_per_cell);
-
-      for (unsigned int child=0; child<this->n_children(); ++child)
-        {
-          Assert (this->child(child)->get_fe().dofs_per_cell == dofs_per_cell,
-                  ExcNotImplemented());
-
-          // prolong the given data
-          // to the present
-          // cell. FullMatrix only
-          // wants us to call vmult
-          // if the matrix size is
-          // actually non-zero, so
-          // check that case
-          if (tmp.size() > 0)
-            {
-              this->get_fe().get_prolongation_matrix(child, this->refinement_case())
-              .vmult (tmp, local_values);
-
-              this->child(child)->set_dof_values_by_interpolation (tmp, values);
-            }
-        }
-    }
-}
-
-
-
 // --------------------------------------------------------------------------
 // explicit instantiations
 #include "dof_accessor.inst"
index 103290a71178172230acd97d6aa97a1ad9a82169..297e98c82910e37775671bbf62d974f571401001 100644 (file)
@@ -165,82 +165,3 @@ for (deal_II_dimension : DIMENSIONS; lda : BOOL)
 #endif
   }
 
-
-for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
-  {
-    template
-      void
-      DoFCellAccessor<DoFHandler<deal_II_dimension>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<DoFHandler<deal_II_dimension>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#if deal_II_dimension != 3
-
-    template
-      void
-      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#endif
-
-#if deal_II_dimension == 3
-
-    template
-      void
-      DoFCellAccessor<DoFHandler<1,3>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<DoFHandler<1,3>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#endif
-
-  }
-
-
-for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
-  {
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<deal_II_dimension>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<deal_II_dimension>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#if deal_II_dimension != 3
-
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#endif
-
-#if deal_II_dimension == 3
-
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<1,3>, lda>::get_interpolated_dof_values
-      (const VEC&, Vector<SCALAR>&) const;
-    template
-      void
-      DoFCellAccessor<hp::DoFHandler<1,3>, lda>::set_dof_values_by_interpolation
-      (const Vector<SCALAR>&, VEC&) const;
-
-#endif
-  }
-
diff --git a/deal.II/source/dofs/dof_accessor_get.cc b/deal.II/source/dofs/dof_accessor_get.cc
new file mode 100644 (file)
index 0000000..9b9ca8b
--- /dev/null
@@ -0,0 +1,125 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/lac/vector.h>
+#include <deal.II/lac/block_vector.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
+#include <deal.II/lac/petsc_vector.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/lac/sparse_matrix.h>
+
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_levels.h>
+#include <deal.II/hp/dof_handler.h>
+#include <deal.II/grid/tria_boundary.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/tria_iterator.templates.h>
+#include <deal.II/fe/fe.h>
+
+#include <vector>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+template <class DH, bool lda>
+template <class InputVector, typename number>
+void
+DoFCellAccessor<DH,lda>::
+get_interpolated_dof_values (const InputVector &values,
+                             Vector<number>    &interpolated_values) const
+{
+  const FiniteElement<dim,spacedim> &fe            = this->get_fe();
+  const unsigned int        dofs_per_cell = fe.dofs_per_cell;
+
+  Assert (this->dof_handler != 0,
+          typename BaseClass::ExcInvalidObject());
+  Assert (&fe != 0,
+          typename BaseClass::ExcInvalidObject());
+  Assert (interpolated_values.size() == dofs_per_cell,
+          typename BaseClass::ExcVectorDoesNotMatch());
+  Assert (values.size() == this->dof_handler->n_dofs(),
+          typename BaseClass::ExcVectorDoesNotMatch());
+
+  if (!this->has_children())
+    // if this cell has no children: simply return the exact values on this
+    // cell
+    this->get_dof_values (values, interpolated_values);
+  else
+    // otherwise clobber them from the children
+    {
+      Vector<number> tmp1(dofs_per_cell);
+      Vector<number> tmp2(dofs_per_cell);
+
+      interpolated_values = 0;
+
+      // later on we will have to push the values interpolated from the child
+      // to the mother cell into the output vector. unfortunately, there are
+      // two types of elements: ones where you add up the contributions from
+      // the different child cells, and ones where you overwrite.
+      //
+      // an example for the first is piecewise constant (and discontinuous)
+      // elements, where we build the value on the coarse cell by averaging
+      // the values from the cell (i.e. by adding up a fraction of the values
+      // of their values)
+      //
+      // an example for the latter are the usual continuous elements. the
+      // value on a vertex of a coarse cell must there be the same,
+      // irrespective of the adjacent cell we are presently on. so we always
+      // overwrite. in fact, we must, since we cannot know in advance how many
+      // neighbors there will be, so there is no way to compute the average
+      // with fixed factors
+      //
+      // so we have to find out to which type this element belongs. the
+      // difficulty is: the finite element may be a composed one, so we can
+      // only hope to do this for each shape function individually. in fact,
+      // there are even weird finite elements (for example the Raviart-Thomas
+      // element) which have shape functions that are additive (interior ones)
+      // and others that are overwriting (face degrees of freedom that need to
+      // be continuous across the face). to avoid checking this over and over
+      // again, we do this once now and cache the results
+      std::vector<bool> restriction_is_additive (dofs_per_cell);
+      for (unsigned int i=0; i<dofs_per_cell; ++i)
+        restriction_is_additive[i] = fe.restriction_is_additive(i);
+
+      for (unsigned int child=0; child<this->n_children(); ++child)
+        {
+          // get the values from the present child, if necessary by
+          // interpolation itself
+          this->child(child)->get_interpolated_dof_values (values,
+                                                           tmp1);
+          // interpolate these to the mother cell
+          fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
+
+          // and add up or set them in the output vector
+          for (unsigned int i=0; i<dofs_per_cell; ++i)
+            if (restriction_is_additive[i])
+              interpolated_values(i) += tmp2(i);
+            else if (tmp2(i) != number())
+              interpolated_values(i) = tmp2(i);
+        }
+    }
+}
+
+
+// --------------------------------------------------------------------------
+// explicit instantiations
+#include "dof_accessor_get.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/dofs/dof_accessor_get.inst.in b/deal.II/source/dofs/dof_accessor_get.inst.in
new file mode 100644 (file)
index 0000000..75d1009
--- /dev/null
@@ -0,0 +1,72 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
+  {
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#if deal_II_dimension != 3
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#endif
+
+#if deal_II_dimension == 3
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<1,3>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#endif
+
+  }
+
+
+for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
+  {
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#if deal_II_dimension != 3
+
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#endif
+
+#if deal_II_dimension == 3
+
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<1,3>, lda>::get_interpolated_dof_values
+      (const VEC&, Vector<SCALAR>&) const;
+
+#endif
+  }
+
diff --git a/deal.II/source/dofs/dof_accessor_set.cc b/deal.II/source/dofs/dof_accessor_set.cc
new file mode 100644 (file)
index 0000000..f11fc84
--- /dev/null
@@ -0,0 +1,93 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/lac/vector.h>
+#include <deal.II/lac/block_vector.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
+#include <deal.II/lac/petsc_vector.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/lac/sparse_matrix.h>
+
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_levels.h>
+#include <deal.II/hp/dof_handler.h>
+#include <deal.II/grid/tria_boundary.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/tria_iterator.templates.h>
+#include <deal.II/fe/fe.h>
+
+#include <vector>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+
+template <class DH, bool lda>
+template <class OutputVector, typename number>
+void
+DoFCellAccessor<DH,lda>::
+set_dof_values_by_interpolation (const Vector<number> &local_values,
+                                 OutputVector         &values) const
+{
+  const unsigned int dofs_per_cell = this->get_fe().dofs_per_cell;
+
+  Assert (this->dof_handler != 0,
+          typename BaseClass::ExcInvalidObject());
+  Assert (&this->get_fe() != 0,
+          typename BaseClass::ExcInvalidObject());
+  Assert (local_values.size() == dofs_per_cell,
+          typename BaseClass::ExcVectorDoesNotMatch());
+  Assert (values.size() == this->dof_handler->n_dofs(),
+          typename BaseClass::ExcVectorDoesNotMatch());
+
+  if (!this->has_children())
+    // if this cell has no children: simply set the values on this cell
+    this->set_dof_values (local_values, values);
+  else
+    // otherwise distribute them to the children
+    {
+      Vector<number> tmp(dofs_per_cell);
+
+      for (unsigned int child=0; child<this->n_children(); ++child)
+        {
+          Assert (this->child(child)->get_fe().dofs_per_cell == dofs_per_cell,
+                  ExcNotImplemented());
+
+          // prolong the given data to the present cell. FullMatrix only wants
+          // us to call vmult if the matrix size is actually non-zero, so
+          // check that case
+          if (tmp.size() > 0)
+            {
+              this->get_fe().get_prolongation_matrix(child, this->refinement_case())
+              .vmult (tmp, local_values);
+
+              this->child(child)->set_dof_values_by_interpolation (tmp, values);
+            }
+        }
+    }
+}
+
+
+
+// --------------------------------------------------------------------------
+// explicit instantiations
+#include "dof_accessor_set.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/dofs/dof_accessor_set.inst.in b/deal.II/source/dofs/dof_accessor_set.inst.in
new file mode 100644 (file)
index 0000000..7494831
--- /dev/null
@@ -0,0 +1,72 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
+  {
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#if deal_II_dimension != 3
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
+
+#if deal_II_dimension == 3
+
+    template
+      void
+      DoFCellAccessor<DoFHandler<1,3>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
+
+  }
+
+
+for (VEC : SERIAL_VECTORS; SCALAR : REAL_SCALARS; deal_II_dimension : DIMENSIONS; lda : BOOL)
+  {
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#if deal_II_dimension != 3
+
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
+
+#if deal_II_dimension == 3
+
+    template
+      void
+      DoFCellAccessor<hp::DoFHandler<1,3>, lda>::set_dof_values_by_interpolation
+      (const Vector<SCALAR>&, VEC&) const;
+
+#endif
+  }
+
index ad41b28892b8cbe4b89e6dfd75744a96bd03dee0..51b5f2ec559e360eb7c6fe395c5b0434e234a4a0 100644 (file)
@@ -41,7 +41,6 @@
 #include <deal.II/hp/q_collection.h>
 #include <deal.II/hp/fe_values.h>
 #include <deal.II/dofs/dof_tools.h>
-#include <deal.II/numerics/vector_tools.h>
 
 #include <deal.II/multigrid/mg_dof_handler.h>
 
@@ -54,3212 +53,6 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace DoFTools
 {
-
-  template <class DH, class SparsityPattern>
-  void
-  make_sparsity_pattern (const DH               &dof,
-                         SparsityPattern        &sparsity,
-                         const ConstraintMatrix &constraints,
-                         const bool              keep_constrained_dofs,
-                         const types::subdomain_id subdomain_id)
-  {
-    const types::global_dof_index n_dofs = dof.n_dofs();
-
-    Assert (sparsity.n_rows() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
-    Assert (sparsity.n_cols() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
-
-    // If we have a distributed::Triangulation only allow locally_owned
-    // subdomain. Not setting a subdomain is also okay, because we skip
-    // ghost cells in the loop below.
-    Assert (
-      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
-      ExcMessage ("For parallel::distributed::Triangulation objects and "
-                  "associated DoF handler objects, asking for any subdomain other "
-                  "than the locally owned one does not make sense."));
-
-    std::vector<types::global_dof_index> dofs_on_this_cell;
-    dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
-    typename DH::active_cell_iterator cell = dof.begin_active(),
-                                      endc = dof.end();
-
-    // In case we work with a distributed sparsity pattern of Trilinos
-    // type, we only have to do the work if the current cell is owned by
-    // the calling processor. Otherwise, just continue.
-    for (; cell!=endc; ++cell)
-      if (((subdomain_id == numbers::invalid_subdomain_id)
-           ||
-           (subdomain_id == cell->subdomain_id()))
-          &&
-          cell->is_locally_owned())
-        {
-          const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
-          dofs_on_this_cell.resize (dofs_per_cell);
-          cell->get_dof_indices (dofs_on_this_cell);
-
-          // make sparsity pattern for this cell. if no constraints pattern
-          // was given, then the following call acts as if simply no
-          // constraints existed
-          constraints.add_entries_local_to_global (dofs_on_this_cell,
-                                                   sparsity,
-                                                   keep_constrained_dofs);
-        }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_sparsity_pattern (const DH                &dof,
-                         const Table<2,Coupling> &couplings,
-                         SparsityPattern         &sparsity,
-                         const ConstraintMatrix  &constraints,
-                         const bool               keep_constrained_dofs,
-                         const types::subdomain_id subdomain_id)
-  {
-    const types::global_dof_index n_dofs = dof.n_dofs();
-
-    Assert (sparsity.n_rows() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
-    Assert (sparsity.n_cols() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
-    Assert (couplings.n_rows() == dof.get_fe().n_components(),
-            ExcDimensionMismatch(couplings.n_rows(), dof.get_fe().n_components()));
-    Assert (couplings.n_cols() == dof.get_fe().n_components(),
-            ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().n_components()));
-
-    // If we have a distributed::Triangulation only allow locally_owned
-    // subdomain. Not setting a subdomain is also okay, because we skip
-    // ghost cells in the loop below.
-    Assert (
-      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
-      ExcMessage ("For parallel::distributed::Triangulation objects and "
-                  "associated DoF handler objects, asking for any subdomain other "
-                  "than the locally owned one does not make sense."));
-
-    const hp::FECollection<DH::dimension,DH::space_dimension> fe_collection (dof.get_fe());
-
-    // first, for each finite element, build a mask for each dof, not like
-    // the one given which represents components. make sure we do the right
-    // thing also with respect to non-primitive shape functions, which
-    // takes some additional thought
-    std::vector<Table<2,bool> > dof_mask(fe_collection.size());
-
-    // check whether the table of couplings contains only true arguments,
-    // i.e., we do not exclude any index. that is the easy case, since we
-    // don't have to set up the tables
-    bool need_dof_mask = false;
-    for (unsigned int i=0; i<couplings.n_rows(); ++i)
-      for (unsigned int j=0; j<couplings.n_cols(); ++j)
-        if (couplings(i,j) == none)
-          need_dof_mask = true;
-
-    if (need_dof_mask == true)
-      for (unsigned int f=0; f<fe_collection.size(); ++f)
-        {
-          const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
-
-          dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
-
-          for (unsigned int i=0; i<dofs_per_cell; ++i)
-            for (unsigned int j=0; j<dofs_per_cell; ++j)
-              if (fe_collection[f].is_primitive(i) &&
-                  fe_collection[f].is_primitive(j))
-                dof_mask[f](i,j)
-                  = (couplings(fe_collection[f].system_to_component_index(i).first,
-                               fe_collection[f].system_to_component_index(j).first) != none);
-              else
-                {
-                  const unsigned int first_nonzero_comp_i
-                    = fe_collection[f].get_nonzero_components(i).first_selected_component();
-                  const unsigned int first_nonzero_comp_j
-                    = fe_collection[f].get_nonzero_components(j).first_selected_component();
-                  Assert (first_nonzero_comp_i < fe_collection[f].n_components(),
-                          ExcInternalError());
-                  Assert (first_nonzero_comp_j < fe_collection[f].n_components(),
-                          ExcInternalError());
-
-                  dof_mask[f](i,j)
-                    = (couplings(first_nonzero_comp_i,first_nonzero_comp_j) != none);
-                }
-        }
-
-
-    std::vector<types::global_dof_index> dofs_on_this_cell(fe_collection.max_dofs_per_cell());
-    typename DH::active_cell_iterator cell = dof.begin_active(),
-                                      endc = dof.end();
-
-    // In case we work with a distributed sparsity pattern of Trilinos
-    // type, we only have to do the work if the current cell is owned by
-    // the calling processor. Otherwise, just continue.
-    for (; cell!=endc; ++cell)
-      if (((subdomain_id == numbers::invalid_subdomain_id)
-           ||
-           (subdomain_id == cell->subdomain_id()))
-          &&
-          cell->is_locally_owned())
-        {
-          const unsigned int fe_index = cell->active_fe_index();
-          const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
-
-          dofs_on_this_cell.resize (dofs_per_cell);
-          cell->get_dof_indices (dofs_on_this_cell);
-
-
-          // make sparsity pattern for this cell. if no constraints pattern
-          // was given, then the following call acts as if simply no
-          // constraints existed
-          constraints.add_entries_local_to_global (dofs_on_this_cell,
-                                                   sparsity,
-                                                   keep_constrained_dofs,
-                                                   dof_mask[fe_index]);
-        }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_sparsity_pattern (
-    const DH        &dof_row,
-    const DH        &dof_col,
-    SparsityPattern &sparsity)
-  {
-    const types::global_dof_index n_dofs_row = dof_row.n_dofs();
-    const types::global_dof_index n_dofs_col = dof_col.n_dofs();
-
-    Assert (sparsity.n_rows() == n_dofs_row,
-            ExcDimensionMismatch (sparsity.n_rows(), n_dofs_row));
-    Assert (sparsity.n_cols() == n_dofs_col,
-            ExcDimensionMismatch (sparsity.n_cols(), n_dofs_col));
-
-//TODO: Looks like wasteful memory management here
-
-    const std::list<std::pair<typename DH::cell_iterator,
-          typename DH::cell_iterator> >
-          cell_list
-          = GridTools::get_finest_common_cells (dof_row, dof_col);
-
-
-    typename std::list<std::pair<typename DH::cell_iterator,
-             typename DH::cell_iterator> >::const_iterator
-             cell_iter = cell_list.begin();
-
-    for (; cell_iter!=cell_list.end(); ++cell_iter)
-      {
-        const typename DH::cell_iterator cell_row = cell_iter->first;
-        const typename DH::cell_iterator cell_col = cell_iter->second;
-
-        if (!cell_row->has_children() && !cell_col->has_children())
-          {
-            const unsigned int dofs_per_cell_row =
-              cell_row->get_fe().dofs_per_cell;
-            const unsigned int dofs_per_cell_col =
-              cell_col->get_fe().dofs_per_cell;
-            std::vector<types::global_dof_index>
-            local_dof_indices_row(dofs_per_cell_row);
-            std::vector<types::global_dof_index>
-            local_dof_indices_col(dofs_per_cell_col);
-            cell_row->get_dof_indices (local_dof_indices_row);
-            cell_col->get_dof_indices (local_dof_indices_col);
-            for (unsigned int i=0; i<dofs_per_cell_row; ++i)
-              sparsity.add_entries (local_dof_indices_row[i],
-                                    local_dof_indices_col.begin(),
-                                    local_dof_indices_col.end());
-          }
-        else if (cell_row->has_children())
-          {
-            const std::vector<typename DH::active_cell_iterator >
-            child_cells = GridTools::get_active_child_cells<DH> (cell_row);
-            for (unsigned int i=0; i<child_cells.size(); i++)
-              {
-                const typename DH::cell_iterator
-                cell_row_child = child_cells[i];
-                const unsigned int dofs_per_cell_row =
-                  cell_row_child->get_fe().dofs_per_cell;
-                const unsigned int dofs_per_cell_col =
-                  cell_col->get_fe().dofs_per_cell;
-                std::vector<types::global_dof_index>
-                local_dof_indices_row(dofs_per_cell_row);
-                std::vector<types::global_dof_index>
-                local_dof_indices_col(dofs_per_cell_col);
-                cell_row_child->get_dof_indices (local_dof_indices_row);
-                cell_col->get_dof_indices (local_dof_indices_col);
-                for (unsigned int i=0; i<dofs_per_cell_row; ++i)
-                  sparsity.add_entries (local_dof_indices_row[i],
-                                        local_dof_indices_col.begin(),
-                                        local_dof_indices_col.end());
-              }
-          }
-        else
-          {
-            std::vector<typename DH::active_cell_iterator>
-            child_cells = GridTools::get_active_child_cells<DH> (cell_col);
-            for (unsigned int i=0; i<child_cells.size(); i++)
-              {
-                const typename DH::active_cell_iterator
-                cell_col_child = child_cells[i];
-                const unsigned int dofs_per_cell_row =
-                  cell_row->get_fe().dofs_per_cell;
-                const unsigned int dofs_per_cell_col =
-                  cell_col_child->get_fe().dofs_per_cell;
-                std::vector<types::global_dof_index>
-                local_dof_indices_row(dofs_per_cell_row);
-                std::vector<types::global_dof_index>
-                local_dof_indices_col(dofs_per_cell_col);
-                cell_row->get_dof_indices (local_dof_indices_row);
-                cell_col_child->get_dof_indices (local_dof_indices_col);
-                for (unsigned int i=0; i<dofs_per_cell_row; ++i)
-                  sparsity.add_entries (local_dof_indices_row[i],
-                                        local_dof_indices_col.begin(),
-                                        local_dof_indices_col.end());
-              }
-          }
-      }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_boundary_sparsity_pattern (
-    const DH                        &dof,
-    const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
-    SparsityPattern                 &sparsity)
-  {
-    if (DH::dimension == 1)
-      {
-        // there are only 2 boundary indicators in 1d, so it is no
-        // performance problem to call the other function
-        typename DH::FunctionMap boundary_indicators;
-        boundary_indicators[0] = 0;
-        boundary_indicators[1] = 0;
-        make_boundary_sparsity_pattern<DH, SparsityPattern> (dof,
-                                                             boundary_indicators,
-                                                             dof_to_boundary_mapping,
-                                                             sparsity);
-        return;
-      }
-
-    const types::global_dof_index n_dofs = dof.n_dofs();
-
-    AssertDimension (dof_to_boundary_mapping.size(), n_dofs);
-    AssertDimension (sparsity.n_rows(), dof.n_boundary_dofs());
-    AssertDimension (sparsity.n_cols(), dof.n_boundary_dofs());
-#ifdef DEBUG
-    if (sparsity.n_rows() != 0)
-      {
-        types::global_dof_index max_element = 0;
-        for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
-             i!=dof_to_boundary_mapping.end(); ++i)
-          if ((*i != DH::invalid_dof_index) &&
-              (*i > max_element))
-            max_element = *i;
-        AssertDimension (max_element, sparsity.n_rows()-1);
-      };
-#endif
-
-    std::vector<types::global_dof_index> dofs_on_this_face;
-    dofs_on_this_face.reserve (max_dofs_per_face(dof));
-
-    // loop over all faces to check whether they are at a boundary. note
-    // that we need not take special care of single lines (using
-    // @p{cell->has_boundary_lines}), since we do not support boundaries of
-    // dimension dim-2, and so every boundary line is also part of a
-    // boundary face.
-    typename DH::active_cell_iterator cell = dof.begin_active(),
-                                      endc = dof.end();
-    for (; cell!=endc; ++cell)
-      for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
-        if (cell->at_boundary(f))
-          {
-            const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
-            dofs_on_this_face.resize (dofs_per_face);
-            cell->face(f)->get_dof_indices (dofs_on_this_face,
-                                            cell->active_fe_index());
-
-            // make sparsity pattern for this cell
-            for (unsigned int i=0; i<dofs_per_face; ++i)
-              for (unsigned int j=0; j<dofs_per_face; ++j)
-                sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
-                              dof_to_boundary_mapping[dofs_on_this_face[j]]);
-          }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void make_boundary_sparsity_pattern (
-    const DH                                        &dof,
-    const typename FunctionMap<DH::space_dimension>::type &boundary_indicators,
-    const std::vector<types::global_dof_index>                 &dof_to_boundary_mapping,
-    SparsityPattern                                 &sparsity)
-  {
-    if (DH::dimension == 1)
-      {
-        // first check left, then right boundary point
-        for (unsigned int direction=0; direction<2; ++direction)
-          {
-            // if this boundary is not requested, then go on with next one
-            if (boundary_indicators.find(direction) ==
-                boundary_indicators.end())
-              continue;
-
-            // find active cell at that boundary: first go to left/right,
-            // then to children
-            typename DH::level_cell_iterator cell = dof.begin(0);
-            while (!cell->at_boundary(direction))
-              cell = cell->neighbor(direction);
-            while (!cell->active())
-              cell = cell->child(direction);
-
-            const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
-            std::vector<types::global_dof_index> boundary_dof_boundary_indices (dofs_per_vertex);
-
-            // next get boundary mapped dof indices of boundary dofs
-            for (unsigned int i=0; i<dofs_per_vertex; ++i)
-              boundary_dof_boundary_indices[i]
-                = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
-
-            for (unsigned int i=0; i<dofs_per_vertex; ++i)
-              sparsity.add_entries (boundary_dof_boundary_indices[i],
-                                    boundary_dof_boundary_indices.begin(),
-                                    boundary_dof_boundary_indices.end());
-          };
-        return;
-      }
-
-    const types::global_dof_index n_dofs = dof.n_dofs();
-
-    AssertDimension (dof_to_boundary_mapping.size(), n_dofs);
-    Assert (boundary_indicators.find(numbers::internal_face_boundary_id) == boundary_indicators.end(),
-            typename DH::ExcInvalidBoundaryIndicator());
-    Assert (sparsity.n_rows() == dof.n_boundary_dofs (boundary_indicators),
-            ExcDimensionMismatch (sparsity.n_rows(), dof.n_boundary_dofs (boundary_indicators)));
-    Assert (sparsity.n_cols() == dof.n_boundary_dofs (boundary_indicators),
-            ExcDimensionMismatch (sparsity.n_cols(), dof.n_boundary_dofs (boundary_indicators)));
-#ifdef DEBUG
-    if (sparsity.n_rows() != 0)
-      {
-        types::global_dof_index max_element = 0;
-        for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
-             i!=dof_to_boundary_mapping.end(); ++i)
-          if ((*i != DH::invalid_dof_index) &&
-              (*i > max_element))
-            max_element = *i;
-        AssertDimension (max_element, sparsity.n_rows()-1);
-      };
-#endif
-
-    std::vector<types::global_dof_index> dofs_on_this_face;
-    dofs_on_this_face.reserve (max_dofs_per_face(dof));
-    typename DH::active_cell_iterator cell = dof.begin_active(),
-                                      endc = dof.end();
-    for (; cell!=endc; ++cell)
-      for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
-        if (boundary_indicators.find(cell->face(f)->boundary_indicator()) !=
-            boundary_indicators.end())
-          {
-            const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
-            dofs_on_this_face.resize (dofs_per_face);
-            cell->face(f)->get_dof_indices (dofs_on_this_face,
-                                            cell->active_fe_index());
-
-            // make sparsity pattern for this cell
-            for (unsigned int i=0; i<dofs_per_face; ++i)
-              for (unsigned int j=0; j<dofs_per_face; ++j)
-                sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
-                              dof_to_boundary_mapping[dofs_on_this_face[j]]);
-          }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_flux_sparsity_pattern (const DH                  &dof,
-                              SparsityPattern           &sparsity,
-                              const ConstraintMatrix    &constraints,
-                              const bool                keep_constrained_dofs,
-                              const types::subdomain_id subdomain_id)
-
-  // TODO: QA: reduce the indentation level of this method..., Maier 2012
-
-  {
-    const types::global_dof_index n_dofs = dof.n_dofs();
-
-    AssertDimension (sparsity.n_rows(), n_dofs);
-    AssertDimension (sparsity.n_cols(), n_dofs);
-
-    // If we have a distributed::Triangulation only allow locally_owned
-    // subdomain. Not setting a subdomain is also okay, because we skip
-    // ghost cells in the loop below.
-    Assert (
-      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == numbers::invalid_subdomain_id)
-      ||
-      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
-      ExcMessage ("For parallel::distributed::Triangulation objects and "
-                  "associated DoF handler objects, asking for any subdomain other "
-                  "than the locally owned one does not make sense."));
-
-    std::vector<types::global_dof_index> dofs_on_this_cell;
-    std::vector<types::global_dof_index> dofs_on_other_cell;
-    dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
-    dofs_on_other_cell.reserve (max_dofs_per_cell(dof));
-    typename DH::active_cell_iterator cell = dof.begin_active(),
-                                      endc = dof.end();
-
-    // TODO: in an old implementation, we used user flags before to tag
-    // faces that were already touched. this way, we could reduce the work
-    // a little bit. now, we instead add only data from one side. this
-    // should be OK, but we need to actually verify it.
-
-    // In case we work with a distributed sparsity pattern of Trilinos
-    // type, we only have to do the work if the current cell is owned by
-    // the calling processor. Otherwise, just continue.
-    for (; cell!=endc; ++cell)
-      if (((subdomain_id == numbers::invalid_subdomain_id)
-           ||
-           (subdomain_id == cell->subdomain_id()))
-          &&
-          cell->is_locally_owned())
-        {
-          const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
-          dofs_on_this_cell.resize (n_dofs_on_this_cell);
-          cell->get_dof_indices (dofs_on_this_cell);
-
-          // make sparsity pattern for this cell. if no constraints pattern
-          // was given, then the following call acts as if simply no
-          // constraints existed
-          constraints.add_entries_local_to_global (dofs_on_this_cell,
-                                                   sparsity,
-                                                   keep_constrained_dofs);
-
-          for (unsigned int face = 0;
-               face < GeometryInfo<DH::dimension>::faces_per_cell;
-               ++face)
-            {
-              typename DH::face_iterator cell_face = cell->face(face);
-              if (! cell->at_boundary(face) )
-                {
-                  typename DH::level_cell_iterator neighbor = cell->neighbor(face);
-
-                  // in 1d, we do not need to worry whether the neighbor
-                  // might have children and then loop over those children.
-                  // rather, we may as well go straight to to cell behind
-                  // this particular cell's most terminal child
-                  if (DH::dimension==1)
-                    while (neighbor->has_children())
-                      neighbor = neighbor->child(face==0 ? 1 : 0);
-
-                  if (neighbor->has_children())
-                    {
-                      for (unsigned int sub_nr = 0;
-                           sub_nr != cell_face->number_of_children();
-                           ++sub_nr)
-                        {
-                          const typename DH::level_cell_iterator
-                          sub_neighbor
-                            = cell->neighbor_child_on_subface (face, sub_nr);
-
-                          const unsigned int n_dofs_on_neighbor
-                            = sub_neighbor->get_fe().dofs_per_cell;
-                          dofs_on_other_cell.resize (n_dofs_on_neighbor);
-                          sub_neighbor->get_dof_indices (dofs_on_other_cell);
-
-                          constraints.add_entries_local_to_global
-                          (dofs_on_this_cell, dofs_on_other_cell,
-                           sparsity, keep_constrained_dofs);
-                          constraints.add_entries_local_to_global
-                          (dofs_on_other_cell, dofs_on_this_cell,
-                           sparsity, keep_constrained_dofs);
-                        }
-                    }
-                  else
-                    {
-                      // Refinement edges are taken care of by coarser
-                      // cells
-
-                      // TODO: in the distributed case, we miss out the
-                      // constraints when the neighbor cell is coarser, but
-                      // only the current cell is owned locally!
-                      if (cell->neighbor_is_coarser(face))
-                        continue;
-
-                      const unsigned int n_dofs_on_neighbor
-                        = neighbor->get_fe().dofs_per_cell;
-                      dofs_on_other_cell.resize (n_dofs_on_neighbor);
-
-                      neighbor->get_dof_indices (dofs_on_other_cell);
-
-                      constraints.add_entries_local_to_global
-                      (dofs_on_this_cell, dofs_on_other_cell,
-                       sparsity, keep_constrained_dofs);
-
-                      // only need to add these in case the neighbor cell
-                      // is not locally owned - otherwise, we touch each
-                      // face twice and hence put the indices the other way
-                      // around
-                      if (!cell->neighbor(face)->active()
-                          ||
-                          (cell->neighbor(face)->subdomain_id() !=
-                           cell->subdomain_id()))
-                        constraints.add_entries_local_to_global
-                        (dofs_on_other_cell, dofs_on_this_cell,
-                         sparsity, keep_constrained_dofs);
-                    }
-                }
-            }
-        }
-  }
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_flux_sparsity_pattern (const DH        &dof,
-                              SparsityPattern &sparsity)
-  {
-    ConstraintMatrix constraints;
-    make_flux_sparsity_pattern (dof, sparsity, constraints);
-  }
-
-
-
-  template <int dim, int spacedim>
-  Table<2,Coupling>
-  dof_couplings_from_component_couplings (const FiniteElement<dim,spacedim> &fe,
-                                          const Table<2,Coupling> &component_couplings)
-  {
-    Assert(component_couplings.n_rows() == fe.n_components(),
-           ExcDimensionMismatch(component_couplings.n_rows(),
-                                fe.n_components()));
-    Assert(component_couplings.n_cols() == fe.n_components(),
-           ExcDimensionMismatch(component_couplings.n_cols(),
-                                fe.n_components()));
-
-    const unsigned int n_dofs = fe.dofs_per_cell;
-
-    Table<2,Coupling> dof_couplings (n_dofs, n_dofs);
-
-    for (unsigned int i=0; i<n_dofs; ++i)
-      {
-        const unsigned int ii
-          = (fe.is_primitive(i) ?
-             fe.system_to_component_index(i).first
-             :
-             fe.get_nonzero_components(i).first_selected_component()
-            );
-        Assert (ii < fe.n_components(), ExcInternalError());
-
-        for (unsigned int j=0; j<n_dofs; ++j)
-          {
-            const unsigned int jj
-              = (fe.is_primitive(j) ?
-                 fe.system_to_component_index(j).first
-                 :
-                 fe.get_nonzero_components(j).first_selected_component()
-                );
-            Assert (jj < fe.n_components(), ExcInternalError());
-
-            dof_couplings(i,j) = component_couplings(ii,jj);
-          }
-      }
-    return dof_couplings;
-  }
-
-
-
-  template <int dim, int spacedim>
-  std::vector<Table<2,Coupling> >
-  dof_couplings_from_component_couplings
-  (const hp::FECollection<dim,spacedim> &fe,
-   const Table<2,Coupling> &component_couplings)
-  {
-    std::vector<Table<2,Coupling> > return_value (fe.size());
-    for (unsigned int i=0; i<fe.size(); ++i)
-      return_value[i]
-        = dof_couplings_from_component_couplings(fe[i], component_couplings);
-
-    return return_value;
-  }
-
-
-
-  namespace internal
-  {
-    namespace
-    {
-
-      // implementation of the same function in namespace DoFTools for
-      // non-hp DoFHandlers
-      template <class DH, class SparsityPattern>
-      void
-      make_flux_sparsity_pattern (const DH                &dof,
-                                  SparsityPattern         &sparsity,
-                                  const Table<2,Coupling> &int_mask,
-                                  const Table<2,Coupling> &flux_mask)
-      {
-        const FiniteElement<DH::dimension,DH::space_dimension> &fe = dof.get_fe();
-
-        std::vector<types::global_dof_index> dofs_on_this_cell(fe.dofs_per_cell);
-        std::vector<types::global_dof_index> dofs_on_other_cell(fe.dofs_per_cell);
-
-        const Table<2,Coupling>
-        int_dof_mask  = dof_couplings_from_component_couplings(fe, int_mask),
-        flux_dof_mask = dof_couplings_from_component_couplings(fe, flux_mask);
-
-        Table<2,bool> support_on_face(fe.dofs_per_cell,
-                                      GeometryInfo<DH::dimension>::faces_per_cell);
-        for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
-          for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
-            support_on_face(i,f) = fe.has_support_on_face(i,f);
-
-        typename DH::active_cell_iterator cell = dof.begin_active(),
-                                          endc = dof.end();
-        for (; cell!=endc; ++cell)
-          if (cell->is_locally_owned())
-            {
-              cell->get_dof_indices (dofs_on_this_cell);
-              // make sparsity pattern for this cell
-              for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
-                for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
-                  if (int_dof_mask(i,j) != none)
-                    sparsity.add (dofs_on_this_cell[i],
-                                  dofs_on_this_cell[j]);
-
-              // Loop over all interior neighbors
-              for (unsigned int face = 0;
-                   face < GeometryInfo<DH::dimension>::faces_per_cell;
-                   ++face)
-                {
-                  const typename DH::face_iterator
-                  cell_face = cell->face(face);
-                  if (cell_face->user_flag_set ())
-                    continue;
-
-                  if (cell->at_boundary (face) )
-                    {
-                      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
-                        {
-                          const bool i_non_zero_i = support_on_face (i, face);
-                          for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
-                            {
-                              const bool j_non_zero_i = support_on_face (j, face);
-
-                              if ((flux_dof_mask(i,j) == always)
-                                  ||
-                                  (flux_dof_mask(i,j) == nonzero
-                                   &&
-                                   i_non_zero_i
-                                   &&
-                                   j_non_zero_i))
-                                sparsity.add (dofs_on_this_cell[i],
-                                              dofs_on_this_cell[j]);
-                            }
-                        }
-                    }
-                  else
-                    {
-                      typename DH::level_cell_iterator
-                      neighbor = cell->neighbor(face);
-                      // Refinement edges are taken care of by coarser
-                      // cells
-                      if (cell->neighbor_is_coarser(face))
-                        continue;
-
-                      typename DH::face_iterator cell_face = cell->face(face);
-                      const unsigned int
-                      neighbor_face = cell->neighbor_of_neighbor(face);
-
-                      if (cell_face->has_children())
-                        {
-                          for (unsigned int sub_nr = 0;
-                               sub_nr != cell_face->n_children();
-                               ++sub_nr)
-                            {
-                              const typename DH::level_cell_iterator
-                              sub_neighbor
-                                = cell->neighbor_child_on_subface (face, sub_nr);
-
-                              sub_neighbor->get_dof_indices (dofs_on_other_cell);
-                              for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
-                                {
-                                  const bool i_non_zero_i = support_on_face (i, face);
-                                  const bool i_non_zero_e = support_on_face (i, neighbor_face);
-                                  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
-                                    {
-                                      const bool j_non_zero_i = support_on_face (j, face);
-                                      const bool j_non_zero_e = support_on_face (j, neighbor_face);
-
-                                      if (flux_dof_mask(i,j) == always)
-                                        {
-                                          sparsity.add (dofs_on_this_cell[i],
-                                                        dofs_on_other_cell[j]);
-                                          sparsity.add (dofs_on_other_cell[i],
-                                                        dofs_on_this_cell[j]);
-                                          sparsity.add (dofs_on_this_cell[i],
-                                                        dofs_on_this_cell[j]);
-                                          sparsity.add (dofs_on_other_cell[i],
-                                                        dofs_on_other_cell[j]);
-                                        }
-                                      else if (flux_dof_mask(i,j) == nonzero)
-                                        {
-                                          if (i_non_zero_i && j_non_zero_e)
-                                            sparsity.add (dofs_on_this_cell[i],
-                                                          dofs_on_other_cell[j]);
-                                          if (i_non_zero_e && j_non_zero_i)
-                                            sparsity.add (dofs_on_other_cell[i],
-                                                          dofs_on_this_cell[j]);
-                                          if (i_non_zero_i && j_non_zero_i)
-                                            sparsity.add (dofs_on_this_cell[i],
-                                                          dofs_on_this_cell[j]);
-                                          if (i_non_zero_e && j_non_zero_e)
-                                            sparsity.add (dofs_on_other_cell[i],
-                                                          dofs_on_other_cell[j]);
-                                        }
-
-                                      if (flux_dof_mask(j,i) == always)
-                                        {
-                                          sparsity.add (dofs_on_this_cell[j],
-                                                        dofs_on_other_cell[i]);
-                                          sparsity.add (dofs_on_other_cell[j],
-                                                        dofs_on_this_cell[i]);
-                                          sparsity.add (dofs_on_this_cell[j],
-                                                        dofs_on_this_cell[i]);
-                                          sparsity.add (dofs_on_other_cell[j],
-                                                        dofs_on_other_cell[i]);
-                                        }
-                                      else if (flux_dof_mask(j,i) == nonzero)
-                                        {
-                                          if (j_non_zero_i && i_non_zero_e)
-                                            sparsity.add (dofs_on_this_cell[j],
-                                                          dofs_on_other_cell[i]);
-                                          if (j_non_zero_e && i_non_zero_i)
-                                            sparsity.add (dofs_on_other_cell[j],
-                                                          dofs_on_this_cell[i]);
-                                          if (j_non_zero_i && i_non_zero_i)
-                                            sparsity.add (dofs_on_this_cell[j],
-                                                          dofs_on_this_cell[i]);
-                                          if (j_non_zero_e && i_non_zero_e)
-                                            sparsity.add (dofs_on_other_cell[j],
-                                                          dofs_on_other_cell[i]);
-                                        }
-                                    }
-                                }
-                              sub_neighbor->face(neighbor_face)->set_user_flag ();
-                            }
-                        }
-                      else
-                        {
-                          neighbor->get_dof_indices (dofs_on_other_cell);
-                          for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
-                            {
-                              const bool i_non_zero_i = support_on_face (i, face);
-                              const bool i_non_zero_e = support_on_face (i, neighbor_face);
-                              for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
-                                {
-                                  const bool j_non_zero_i = support_on_face (j, face);
-                                  const bool j_non_zero_e = support_on_face (j, neighbor_face);
-                                  if (flux_dof_mask(i,j) == always)
-                                    {
-                                      sparsity.add (dofs_on_this_cell[i],
-                                                    dofs_on_other_cell[j]);
-                                      sparsity.add (dofs_on_other_cell[i],
-                                                    dofs_on_this_cell[j]);
-                                      sparsity.add (dofs_on_this_cell[i],
-                                                    dofs_on_this_cell[j]);
-                                      sparsity.add (dofs_on_other_cell[i],
-                                                    dofs_on_other_cell[j]);
-                                    }
-                                  if (flux_dof_mask(i,j) == nonzero)
-                                    {
-                                      if (i_non_zero_i && j_non_zero_e)
-                                        sparsity.add (dofs_on_this_cell[i],
-                                                      dofs_on_other_cell[j]);
-                                      if (i_non_zero_e && j_non_zero_i)
-                                        sparsity.add (dofs_on_other_cell[i],
-                                                      dofs_on_this_cell[j]);
-                                      if (i_non_zero_i && j_non_zero_i)
-                                        sparsity.add (dofs_on_this_cell[i],
-                                                      dofs_on_this_cell[j]);
-                                      if (i_non_zero_e && j_non_zero_e)
-                                        sparsity.add (dofs_on_other_cell[i],
-                                                      dofs_on_other_cell[j]);
-                                    }
-
-                                  if (flux_dof_mask(j,i) == always)
-                                    {
-                                      sparsity.add (dofs_on_this_cell[j],
-                                                    dofs_on_other_cell[i]);
-                                      sparsity.add (dofs_on_other_cell[j],
-                                                    dofs_on_this_cell[i]);
-                                      sparsity.add (dofs_on_this_cell[j],
-                                                    dofs_on_this_cell[i]);
-                                      sparsity.add (dofs_on_other_cell[j],
-                                                    dofs_on_other_cell[i]);
-                                    }
-                                  if (flux_dof_mask(j,i) == nonzero)
-                                    {
-                                      if (j_non_zero_i && i_non_zero_e)
-                                        sparsity.add (dofs_on_this_cell[j],
-                                                      dofs_on_other_cell[i]);
-                                      if (j_non_zero_e && i_non_zero_i)
-                                        sparsity.add (dofs_on_other_cell[j],
-                                                      dofs_on_this_cell[i]);
-                                      if (j_non_zero_i && i_non_zero_i)
-                                        sparsity.add (dofs_on_this_cell[j],
-                                                      dofs_on_this_cell[i]);
-                                      if (j_non_zero_e && i_non_zero_e)
-                                        sparsity.add (dofs_on_other_cell[j],
-                                                      dofs_on_other_cell[i]);
-                                    }
-                                }
-                            }
-                          neighbor->face(neighbor_face)->set_user_flag ();
-                        }
-                    }
-                }
-            }
-      }
-
-
-      // implementation of the same function in namespace DoFTools for
-      // non-hp DoFHandlers
-      template <int dim, int spacedim, class SparsityPattern>
-      void
-      make_flux_sparsity_pattern (const dealii::hp::DoFHandler<dim,spacedim> &dof,
-                                  SparsityPattern                           &sparsity,
-                                  const Table<2,Coupling> &int_mask,
-                                  const Table<2,Coupling> &flux_mask)
-      {
-        // while the implementation above is quite optimized and caches a
-        // lot of data (see e.g. the int/flux_dof_mask tables), this is no
-        // longer practical for the hp version since we would have to have
-        // it for all combinations of elements in the hp::FECollection.
-        // consequently, the implementation here is simpler and probably
-        // less efficient but at least readable...
-
-        const dealii::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
-
-        std::vector<types::global_dof_index> dofs_on_this_cell(DoFTools::max_dofs_per_cell(dof));
-        std::vector<types::global_dof_index> dofs_on_other_cell(DoFTools::max_dofs_per_cell(dof));
-
-        const std::vector<Table<2,Coupling> >
-        int_dof_mask
-          = dof_couplings_from_component_couplings(fe, int_mask);
-
-        typename dealii::hp::DoFHandler<dim,spacedim>::active_cell_iterator
-        cell = dof.begin_active(),
-        endc = dof.end();
-        for (; cell!=endc; ++cell)
-          {
-            dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
-            cell->get_dof_indices (dofs_on_this_cell);
-
-            // make sparsity pattern for this cell
-            for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
-              for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
-                if (int_dof_mask[cell->active_fe_index()](i,j) != none)
-                  sparsity.add (dofs_on_this_cell[i],
-                                dofs_on_this_cell[j]);
-
-            // Loop over all interior neighbors
-            for (unsigned int face = 0;
-                 face < GeometryInfo<dim>::faces_per_cell;
-                 ++face)
-              {
-                const typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
-                cell_face = cell->face(face);
-                if (cell_face->user_flag_set ())
-                  continue;
-
-                if (cell->at_boundary (face) )
-                  {
-                    for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
-                      for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
-                        if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                       cell->get_fe().system_to_component_index(j).first)
-                             == always)
-                            ||
-                            (flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                       cell->get_fe().system_to_component_index(j).first)
-                             == nonzero))
-                          sparsity.add (dofs_on_this_cell[i],
-                                        dofs_on_this_cell[j]);
-                  }
-                else
-                  {
-                    typename dealii::hp::DoFHandler<dim,spacedim>::level_cell_iterator
-                    neighbor = cell->neighbor(face);
-
-                    // Refinement edges are taken care of by coarser cells
-                    if (cell->neighbor_is_coarser(face))
-                      continue;
-
-                    typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
-                    cell_face = cell->face(face);
-                    const unsigned int
-                    neighbor_face = cell->neighbor_of_neighbor(face);
-
-                    if (cell_face->has_children())
-                      {
-                        for (unsigned int sub_nr = 0;
-                             sub_nr != cell_face->n_children();
-                             ++sub_nr)
-                          {
-                            const typename dealii::hp::DoFHandler<dim,spacedim>::level_cell_iterator
-                            sub_neighbor
-                              = cell->neighbor_child_on_subface (face, sub_nr);
-
-                            dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
-                            sub_neighbor->get_dof_indices (dofs_on_other_cell);
-                            for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
-                              {
-                                for (unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
-                                     ++j)
-                                  {
-                                    if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                                   sub_neighbor->get_fe().system_to_component_index(j).first)
-                                         == always)
-                                        ||
-                                        (flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                                   sub_neighbor->get_fe().system_to_component_index(j).first)
-                                         == nonzero))
-                                      {
-                                        sparsity.add (dofs_on_this_cell[i],
-                                                      dofs_on_other_cell[j]);
-                                        sparsity.add (dofs_on_other_cell[i],
-                                                      dofs_on_this_cell[j]);
-                                        sparsity.add (dofs_on_this_cell[i],
-                                                      dofs_on_this_cell[j]);
-                                        sparsity.add (dofs_on_other_cell[i],
-                                                      dofs_on_other_cell[j]);
-                                      }
-
-                                    if ((flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
-                                                   cell->get_fe().system_to_component_index(i).first)
-                                         == always)
-                                        ||
-                                        (flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
-                                                   cell->get_fe().system_to_component_index(i).first)
-                                         == nonzero))
-                                      {
-                                        sparsity.add (dofs_on_this_cell[j],
-                                                      dofs_on_other_cell[i]);
-                                        sparsity.add (dofs_on_other_cell[j],
-                                                      dofs_on_this_cell[i]);
-                                        sparsity.add (dofs_on_this_cell[j],
-                                                      dofs_on_this_cell[i]);
-                                        sparsity.add (dofs_on_other_cell[j],
-                                                      dofs_on_other_cell[i]);
-                                      }
-                                  }
-                              }
-                            sub_neighbor->face(neighbor_face)->set_user_flag ();
-                          }
-                      }
-                    else
-                      {
-                        dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
-                        neighbor->get_dof_indices (dofs_on_other_cell);
-                        for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
-                          {
-                            for (unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
-                              {
-                                if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                               neighbor->get_fe().system_to_component_index(j).first)
-                                     == always)
-                                    ||
-                                    (flux_mask(cell->get_fe().system_to_component_index(i).first,
-                                               neighbor->get_fe().system_to_component_index(j).first)
-                                     == nonzero))
-                                  {
-                                    sparsity.add (dofs_on_this_cell[i],
-                                                  dofs_on_other_cell[j]);
-                                    sparsity.add (dofs_on_other_cell[i],
-                                                  dofs_on_this_cell[j]);
-                                    sparsity.add (dofs_on_this_cell[i],
-                                                  dofs_on_this_cell[j]);
-                                    sparsity.add (dofs_on_other_cell[i],
-                                                  dofs_on_other_cell[j]);
-                                  }
-
-                                if ((flux_mask(neighbor->get_fe().system_to_component_index(j).first,
-                                               cell->get_fe().system_to_component_index(i).first)
-                                     == always)
-                                    ||
-                                    (flux_mask(neighbor->get_fe().system_to_component_index(j).first,
-                                               cell->get_fe().system_to_component_index(i).first)
-                                     == nonzero))
-                                  {
-                                    sparsity.add (dofs_on_this_cell[j],
-                                                  dofs_on_other_cell[i]);
-                                    sparsity.add (dofs_on_other_cell[j],
-                                                  dofs_on_this_cell[i]);
-                                    sparsity.add (dofs_on_this_cell[j],
-                                                  dofs_on_this_cell[i]);
-                                    sparsity.add (dofs_on_other_cell[j],
-                                                  dofs_on_other_cell[i]);
-                                  }
-                              }
-                          }
-                        neighbor->face(neighbor_face)->set_user_flag ();
-                      }
-                  }
-              }
-          }
-      }
-    }
-
-  }
-
-
-
-
-  template <class DH, class SparsityPattern>
-  void
-  make_flux_sparsity_pattern (const DH                &dof,
-                              SparsityPattern         &sparsity,
-                              const Table<2,Coupling> &int_mask,
-                              const Table<2,Coupling> &flux_mask)
-  {
-    // do the error checking and frame code here, and then pass on to more
-    // specialized functions in the internal namespace
-    const types::global_dof_index n_dofs = dof.n_dofs();
-    const unsigned int n_comp = dof.get_fe().n_components();
-
-    Assert (sparsity.n_rows() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
-    Assert (sparsity.n_cols() == n_dofs,
-            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
-    Assert (int_mask.n_rows() == n_comp,
-            ExcDimensionMismatch (int_mask.n_rows(), n_comp));
-    Assert (int_mask.n_cols() == n_comp,
-            ExcDimensionMismatch (int_mask.n_cols(), n_comp));
-    Assert (flux_mask.n_rows() == n_comp,
-            ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
-    Assert (flux_mask.n_cols() == n_comp,
-            ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
-
-    // Clear user flags because we will need them. But first we save them
-    // and make sure that we restore them later such that at the end of
-    // this function the Triangulation will be in the same state as it was
-    // at the beginning of this function.
-    std::vector<bool> user_flags;
-    dof.get_tria().save_user_flags(user_flags);
-    const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).clear_user_flags ();
-
-    internal::make_flux_sparsity_pattern (dof, sparsity,
-                                          int_mask, flux_mask);
-
-    // finally restore the user flags
-    const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).load_user_flags(user_flags);
-  }
-
-
-
-
-  namespace internal
-  {
-    namespace
-    {
-      inline bool
-      check_master_dof_list (const FullMatrix<double> &face_interpolation_matrix,
-                             const std::vector<types::global_dof_index> &master_dof_list)
-      {
-        const unsigned int N = master_dof_list.size();
-
-        FullMatrix<double> tmp (N,N);
-        for (unsigned int i=0; i<N; ++i)
-          for (unsigned int j=0; j<N; ++j)
-            tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
-
-        // then use the algorithm from FullMatrix::gauss_jordan on this
-        // matrix to find out whether it is singular. the algorithm there
-        // does piviting and at the end swaps rows back into their proper
-        // order -- we omit this step here, since we don't care about the
-        // inverse matrix, all we care about is whether the matrix is
-        // regular or singular
-
-        // first get an estimate of the size of the elements of this
-        // matrix, for later checks whether the pivot element is large
-        // enough, or whether we have to fear that the matrix is not
-        // regular
-        double diagonal_sum = 0;
-        for (unsigned int i=0; i<N; ++i)
-          diagonal_sum += std::fabs(tmp(i,i));
-        const double typical_diagonal_element = diagonal_sum/N;
-
-        // initialize the array that holds the permutations that we find
-        // during pivot search
-        std::vector<unsigned int> p(N);
-        for (unsigned int i=0; i<N; ++i)
-          p[i] = i;
-
-        for (unsigned int j=0; j<N; ++j)
-          {
-            // pivot search: search that part of the line on and right of
-            // the diagonal for the largest element
-            double       max = std::fabs(tmp(j,j));
-            unsigned int r   = j;
-            for (unsigned int i=j+1; i<N; ++i)
-              {
-                if (std::fabs(tmp(i,j)) > max)
-                  {
-                    max = std::fabs(tmp(i,j));
-                    r = i;
-                  }
-              }
-            // check whether the pivot is too small. if that is the case,
-            // then the matrix is singular and we shouldn't use this set of
-            // master dofs
-            if (max < 1.e-12*typical_diagonal_element)
-              return false;
-
-            // row interchange
-            if (r>j)
-              {
-                for (unsigned int k=0; k<N; ++k)
-                  std::swap (tmp(j,k), tmp(r,k));
-
-                std::swap (p[j], p[r]);
-              }
-
-            // transformation
-            const double hr = 1./tmp(j,j);
-            tmp(j,j) = hr;
-            for (unsigned int k=0; k<N; ++k)
-              {
-                if (k==j) continue;
-                for (unsigned int i=0; i<N; ++i)
-                  {
-                    if (i==j) continue;
-                    tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
-                  }
-              }
-            for (unsigned int i=0; i<N; ++i)
-              {
-                tmp(i,j) *= hr;
-                tmp(j,i) *= -hr;
-              }
-            tmp(j,j) = hr;
-          }
-
-        // everything went fine, so we can accept this set of master dofs
-        // (at least as far as they have already been collected)
-        return true;
-      }
-
-
-
-      /**
-       * When restricting, on a face, the degrees of freedom of fe1 to the
-       * space described by fe2 (for example for the complex case described
-       * in the @ref hp_paper "hp paper"), we have to select
-       * fe2.dofs_per_face out of the fe1.dofs_per_face face DoFs as the
-       * master DoFs, and the rest become slave dofs. This function selects
-       * which ones will be masters, and which ones will be slaves.
-       *
-       * The function assumes that master_dofs already has size
-       * fe1.dofs_per_face. After the function, exactly fe2.dofs_per_face
-       * entries will be true.
-       *
-       * The function is a bit complicated since it has to figure out a set
-       * a DoFs so that the corresponding rows in the face interpolation
-       * matrix are all linearly independent. we have a good heuristic (see
-       * the function body) for selecting these rows, but there are cases
-       * where this fails and we have to pick them differently. what we do
-       * is to run the heuristic and then go back to determine whether we
-       * have a set of rows with full row rank. if this isn't the case, go
-       * back and select dofs differently
-       */
-      template <int dim, int spacedim>
-      void
-      select_master_dofs_for_face_restriction (const FiniteElement<dim,spacedim> &fe1,
-                                               const FiniteElement<dim,spacedim> &fe2,
-                                               const FullMatrix<double> &face_interpolation_matrix,
-                                               std::vector<bool>        &master_dof_mask)
-      {
-        Assert (fe1.dofs_per_face >= fe2.dofs_per_face,
-                ExcInternalError());
-        AssertDimension (master_dof_mask.size(), fe1.dofs_per_face);
-
-        Assert (fe2.dofs_per_vertex <= fe1.dofs_per_vertex,
-                ExcInternalError());
-        Assert (fe2.dofs_per_line <= fe1.dofs_per_line,
-                ExcInternalError());
-        Assert ((dim < 3)
-                ||
-                (fe2.dofs_per_quad <= fe1.dofs_per_quad),
-                ExcInternalError());
-
-        // the idea here is to designate as many DoFs in fe1 per object
-        // (vertex, line, quad) as master as there are such dofs in fe2
-        // (indices are int, because we want to avoid the 'unsigned int < 0
-        // is always false warning for the cases at the bottom in 1d and
-        // 2d)
-        //
-        // as mentioned in the paper, it is not always easy to find a set
-        // of master dofs that produces an invertible matrix. to this end,
-        // we check in each step whether the matrix is still invertible and
-        // simply discard this dof if the matrix is not invertible anymore.
-        //
-        // the cases where we did have trouble in the past were with adding
-        // more quad dofs when Q3 and Q4 elements meet at a refined face in
-        // 3d (see the hp/crash_12 test that tests that we can do exactly
-        // this, and failed before we had code to compensate for this
-        // case). the other case are system elements: if we have say a Q1Q2
-        // vs a Q2Q3 element, then we can't just take all master dofs on a
-        // line from a single base element, since the shape functions of
-        // that base element are independent of that of the other one. this
-        // latter case shows up when running hp/hp_constraints_q_system_06
-
-        std::vector<types::global_dof_index> master_dof_list;
-        unsigned int index = 0;
-        for (int v=0;
-             v<static_cast<signed int>(GeometryInfo<dim>::vertices_per_face);
-             ++v)
-          {
-            unsigned int dofs_added = 0;
-            unsigned int i          = 0;
-            while (dofs_added < fe2.dofs_per_vertex)
-              {
-                // make sure that we were able to find a set of master dofs
-                // and that the code down below didn't just reject all our
-                // efforts
-                Assert (i < fe1.dofs_per_vertex,
-                        ExcInternalError());
-
-                // tentatively push this vertex dof
-                master_dof_list.push_back (index+i);
-
-                // then see what happens. if it succeeds, fine
-                if (check_master_dof_list (face_interpolation_matrix,
-                                           master_dof_list)
-                    == true)
-                  ++dofs_added;
-                else
-                  // well, it didn't. simply pop that dof from the list
-                  // again and try with the next dof
-                  master_dof_list.pop_back ();
-
-                // forward counter by one
-                ++i;
-              }
-            index += fe1.dofs_per_vertex;
-          }
-
-        for (int l=0;
-             l<static_cast<signed int>(GeometryInfo<dim>::lines_per_face);
-             ++l)
-          {
-            // same algorithm as above
-            unsigned int dofs_added = 0;
-            unsigned int i          = 0;
-            while (dofs_added < fe2.dofs_per_line)
-              {
-                Assert (i < fe1.dofs_per_line,
-                        ExcInternalError());
-
-                master_dof_list.push_back (index+i);
-                if (check_master_dof_list (face_interpolation_matrix,
-                                           master_dof_list)
-                    == true)
-                  ++dofs_added;
-                else
-                  master_dof_list.pop_back ();
-
-                ++i;
-              }
-            index += fe1.dofs_per_line;
-          }
-
-        for (int q=0;
-             q<static_cast<signed int>(GeometryInfo<dim>::quads_per_face);
-             ++q)
-          {
-            // same algorithm as above
-            unsigned int dofs_added = 0;
-            unsigned int i          = 0;
-            while (dofs_added < fe2.dofs_per_quad)
-              {
-                Assert (i < fe1.dofs_per_quad,
-                        ExcInternalError());
-
-                master_dof_list.push_back (index+i);
-                if (check_master_dof_list (face_interpolation_matrix,
-                                           master_dof_list)
-                    == true)
-                  ++dofs_added;
-                else
-                  master_dof_list.pop_back ();
-
-                ++i;
-              }
-            index += fe1.dofs_per_quad;
-          }
-
-        AssertDimension (index, fe1.dofs_per_face);
-        AssertDimension (master_dof_list.size(), fe2.dofs_per_face);
-
-        // finally copy the list into the mask
-        std::fill (master_dof_mask.begin(), master_dof_mask.end(), false);
-        for (std::vector<types::global_dof_index>::const_iterator i=master_dof_list.begin();
-             i!=master_dof_list.end(); ++i)
-          master_dof_mask[*i] = true;
-      }
-
-
-
-      /**
-       * Make sure that the mask exists that determines which dofs will be
-       * the masters on refined faces where an fe1 and a fe2 meet.
-       */
-      template <int dim, int spacedim>
-      void
-      ensure_existence_of_master_dof_mask (const FiniteElement<dim,spacedim> &fe1,
-                                           const FiniteElement<dim,spacedim> &fe2,
-                                           const FullMatrix<double> &face_interpolation_matrix,
-                                           std_cxx1x::shared_ptr<std::vector<bool> > &master_dof_mask)
-      {
-        if (master_dof_mask == std_cxx1x::shared_ptr<std::vector<bool> >())
-          {
-            master_dof_mask = std_cxx1x::shared_ptr<std::vector<bool> >
-                              (new std::vector<bool> (fe1.dofs_per_face));
-            select_master_dofs_for_face_restriction (fe1,
-                                                     fe2,
-                                                     face_interpolation_matrix,
-                                                     *master_dof_mask);
-          }
-      }
-
-
-
-      /**
-       * Make sure that the given @p face_interpolation_matrix pointer
-       * points to a valid matrix. If the pointer is zero beforehand,
-       * create an entry with the correct data. If it is nonzero, don't
-       * touch it.
-       */
-      template <int dim, int spacedim>
-      void
-      ensure_existence_of_face_matrix (const FiniteElement<dim,spacedim> &fe1,
-                                       const FiniteElement<dim,spacedim> &fe2,
-                                       std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
-      {
-        if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
-          {
-            matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
-                     (new FullMatrix<double> (fe2.dofs_per_face,
-                                              fe1.dofs_per_face));
-            fe1.get_face_interpolation_matrix (fe2,
-                                               *matrix);
-          }
-      }
-
-
-
-      /**
-       * Same, but for subface interpolation matrices.
-       */
-      template <int dim, int spacedim>
-      void
-      ensure_existence_of_subface_matrix (const FiniteElement<dim,spacedim> &fe1,
-                                          const FiniteElement<dim,spacedim> &fe2,
-                                          const unsigned int        subface,
-                                          std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
-      {
-        if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
-          {
-            matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
-                     (new FullMatrix<double> (fe2.dofs_per_face,
-                                              fe1.dofs_per_face));
-            fe1.get_subface_interpolation_matrix (fe2,
-                                                  subface,
-                                                  *matrix);
-          }
-      }
-
-
-
-      /**
-       * Given the face interpolation matrix between two elements, split it
-       * into its master and slave parts and invert the master part as
-       * explained in the @ref hp_paper "hp paper".
-       */
-      void
-      ensure_existence_of_split_face_matrix (const FullMatrix<double> &face_interpolation_matrix,
-                                             const std::vector<bool> &master_dof_mask,
-                                             std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > &split_matrix)
-      {
-        AssertDimension (master_dof_mask.size(), face_interpolation_matrix.m());
-        Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(), true) ==
-                static_cast<signed int>(face_interpolation_matrix.n()),
-                ExcInternalError());
-
-        if (split_matrix ==
-            std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >())
-          {
-            split_matrix
-              = std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >
-                (new std::pair<FullMatrix<double>,FullMatrix<double> >());
-
-            const unsigned int n_master_dofs = face_interpolation_matrix.n();
-            const unsigned int n_dofs        = face_interpolation_matrix.m();
-
-            Assert (n_master_dofs <= n_dofs, ExcInternalError());
-
-            // copy and invert the master
-            // component, copy the slave
-            // component
-            split_matrix->first.reinit (n_master_dofs, n_master_dofs);
-            split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
-
-            unsigned int nth_master_dof = 0,
-                         nth_slave_dof  = 0;
-
-            for (unsigned int i=0; i<n_dofs; ++i)
-              if (master_dof_mask[i] == true)
-                {
-                  for (unsigned int j=0; j<n_master_dofs; ++j)
-                    split_matrix->first(nth_master_dof,j)
-                      = face_interpolation_matrix(i,j);
-                  ++nth_master_dof;
-                }
-              else
-                {
-                  for (unsigned int j=0; j<n_master_dofs; ++j)
-                    split_matrix->second(nth_slave_dof,j)
-                      = face_interpolation_matrix(i,j);
-                  ++nth_slave_dof;
-                }
-
-            AssertDimension (nth_master_dof, n_master_dofs);
-            AssertDimension (nth_slave_dof, n_dofs-n_master_dofs);
-
-            //TODO[WB]: We should make sure very small entries are removed after inversion
-            split_matrix->first.gauss_jordan ();
-          }
-      }
-
-
-      // a template that can determine statically whether a given
-      // DoFHandler class supports different finite element elements
-      template <typename>
-      struct DoFHandlerSupportsDifferentFEs
-      {
-        static const bool value = true;
-      };
-
-
-      template <int dim, int spacedim>
-      struct DoFHandlerSupportsDifferentFEs< dealii::DoFHandler<dim,spacedim> >
-      {
-        static const bool value = false;
-      };
-
-
-      template <int dim, int spacedim>
-      struct DoFHandlerSupportsDifferentFEs< dealii::MGDoFHandler<dim,spacedim> >
-      {
-        static const bool value = false;
-      };
-
-
-      /**
-       * A function that returns how many different finite elements a dof
-       * handler uses. This is one for non-hp DoFHandlers and
-       * dof_handler.get_fe().size() for the hp-versions.
-       */
-      template <int dim, int spacedim>
-      unsigned int
-      n_finite_elements (const dealii::hp::DoFHandler<dim,spacedim> &dof_handler)
-      {
-        return dof_handler.get_fe().size();
-      }
-
-
-      template <class DH>
-      unsigned int
-      n_finite_elements (const DH &)
-      {
-        return 1;
-      }
-
-
-      /**
-       * For a given face belonging to an active cell that borders to a
-       * more refined cell, return the fe_index of the most dominating
-       * finite element used on any of the face's subfaces.
-       */
-      template <typename face_iterator>
-      unsigned int
-      get_most_dominating_subface_fe_index (const face_iterator &face)
-      {
-        const unsigned int dim
-          = face_iterator::AccessorType::dimension;
-        const unsigned int spacedim
-          = face_iterator::AccessorType::space_dimension;
-
-        unsigned int dominating_subface_no = 0;
-        for (; dominating_subface_no<face->n_children();
-             ++dominating_subface_no)
-          {
-            // each of the subfaces can have only a single fe_index
-            // associated with them, since there is no cell on the other
-            // side
-            Assert (face->child(dominating_subface_no)
-                    ->n_active_fe_indices()
-                    == 1,
-                    ExcInternalError());
-
-            const FiniteElement<dim,spacedim> &
-            this_subface_fe = (face->child(dominating_subface_no)
-                               ->get_fe (face->child(dominating_subface_no)
-                                         ->nth_active_fe_index(0)));
-
-            FiniteElementDomination::Domination
-            domination = FiniteElementDomination::either_element_can_dominate;
-            for (unsigned int sf=0; sf<face->n_children(); ++sf)
-              if (sf != dominating_subface_no)
-                {
-                  const FiniteElement<dim,spacedim> &
-                  that_subface_fe = (face->child(sf)
-                                     ->get_fe (face->child(sf)
-                                               ->nth_active_fe_index(0)));
-
-                  domination = domination &
-                               this_subface_fe.compare_for_face_domination(that_subface_fe);
-                }
-
-            // see if the element on this subface is able to dominate the
-            // ones on all other subfaces, and if so take it
-            if ((domination == FiniteElementDomination::this_element_dominates)
-                ||
-                (domination == FiniteElementDomination::either_element_can_dominate))
-              break;
-          }
-
-        // check that we have found one such subface
-        Assert (dominating_subface_no < face->n_children(),
-                ExcNotImplemented());
-
-        // return the finite element index used on it. note that only a
-        // single fe can be active on such subfaces
-        return face->child (dominating_subface_no)->nth_active_fe_index(0);
-      }
-
-
-
-      /**
-       * Copy constraints into a constraint matrix object.
-       *
-       * This function removes zero constraints and those, which constrain
-       * a DoF which was already eliminated in one of the previous steps of
-       * the hp hanging node procedure.
-       *
-       * It also suppresses very small entries in the constraint matrix to
-       * avoid making the sparsity pattern fuller than necessary.
-       */
-      void
-      filter_constraints (const std::vector<types::global_dof_index> &master_dofs,
-                          const std::vector<types::global_dof_index> &slave_dofs,
-                          const FullMatrix<double> &face_constraints,
-                          ConstraintMatrix &constraints)
-      {
-        Assert (face_constraints.n () == master_dofs.size (),
-                ExcDimensionMismatch(master_dofs.size (),
-                                     face_constraints.n()));
-        Assert (face_constraints.m () == slave_dofs.size (),
-                ExcDimensionMismatch(slave_dofs.size (),
-                                     face_constraints.m()));
-
-        const unsigned int n_master_dofs = master_dofs.size ();
-        const unsigned int n_slave_dofs = slave_dofs.size ();
-
-        // check for a couple conditions that happened in parallel
-        // distributed mode
-        for (unsigned int row=0; row!=n_slave_dofs; ++row)
-          Assert (slave_dofs[row] != numbers::invalid_dof_index,
-                  ExcInternalError());
-        for (unsigned int col=0; col!=n_master_dofs; ++col)
-          Assert (master_dofs[col] != numbers::invalid_dof_index,
-                  ExcInternalError());
-
-
-        for (unsigned int row=0; row!=n_slave_dofs; ++row)
-          if (constraints.is_constrained (slave_dofs[row]) == false)
-            {
-              bool constraint_already_satisfied = false;
-
-              // Check if we have an identity constraint, which is already
-              // satisfied by unification of the corresponding global dof
-              // indices
-              for (unsigned int i=0; i<n_master_dofs; ++i)
-                if (face_constraints (row,i) == 1.0)
-                  if (master_dofs[i] == slave_dofs[row])
-                    {
-                      constraint_already_satisfied = true;
-                      break;
-                    }
-
-              if (constraint_already_satisfied == false)
-                {
-                  // add up the absolute values of all constraints in this
-                  // line to get a measure of their absolute size
-                  double abs_sum = 0;
-                  for (unsigned int i=0; i<n_master_dofs; ++i)
-                    abs_sum += std::abs (face_constraints(row,i));
-
-                  // then enter those constraints that are larger than
-                  // 1e-14*abs_sum. everything else probably originated
-                  // from inexact inversion of matrices and similar
-                  // effects. having those constraints in here will only
-                  // lead to problems because it makes sparsity patterns
-                  // fuller than necessary without producing any
-                  // significant effect
-                  constraints.add_line (slave_dofs[row]);
-                  for (unsigned int i=0; i<n_master_dofs; ++i)
-                    if ((face_constraints(row,i) != 0)
-                        &&
-                        (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
-                      constraints.add_entry (slave_dofs[row],
-                                             master_dofs[i],
-                                             face_constraints (row,i));
-                  constraints.set_inhomogeneity (slave_dofs[row], 0.);
-                }
-            }
-      }
-
-    }
-
-
-
-    void
-    make_hp_hanging_node_constraints (const dealii::DoFHandler<1> &,
-                                      ConstraintMatrix &)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-
-    void
-    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1> &,
-                                            ConstraintMatrix &,
-                                            dealii::internal::int2type<1>)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-    void
-    make_hp_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
-                                      ConstraintMatrix &)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-
-    void
-    make_oldstyle_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
-                                            ConstraintMatrix &,
-                                            dealii::internal::int2type<1>)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-    void
-    make_hp_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
-                                      ConstraintMatrix        &/*constraints*/)
-    {
-      // we may have to compute constraints for vertices. gotta think about
-      // that a bit more
-
-      //TODO[WB]: think about what to do here...
-    }
-
-
-
-    void
-    make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
-                                            ConstraintMatrix        &/*constraints*/,
-                                            dealii::internal::int2type<1>)
-    {
-      // we may have to compute constraints for vertices. gotta think about
-      // that a bit more
-
-      //TODO[WB]: think about what to do here...
-    }
-
-
-    void
-    make_hp_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
-                                      ConstraintMatrix &)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-
-    void
-    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
-                                            ConstraintMatrix &,
-                                            dealii::internal::int2type<1>)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-    void
-    make_hp_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
-                                      ConstraintMatrix &)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-    void
-    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
-                                            ConstraintMatrix &,
-                                            dealii::internal::int2type<1>)
-    {
-      // nothing to do for regular dof handlers in 1d
-    }
-
-
-//   currently not used but may be in the future:
-
-//     void
-//     make_hp_hanging_node_constraints (const dealii::MDoFHandler<1,2> &,
-//                                    ConstraintMatrix    &)
-//     {
-//                                     // nothing to do for regular
-//                                     // dof handlers in 1d
-//     }
-
-
-
-//     void
-//     make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
-//                                          ConstraintMatrix    &,
-//                                          dealii::internal::int2type<1>)
-//     {
-//                                     // nothing to do for regular
-//                                     // dof handlers in 1d
-//     }
-
-
-//     void
-//     make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1,2> &/*dof_handler*/,
-//                                          ConstraintMatrix        &/*constraints*/,
-//                                          dealii::internal::int2type<1>)
-//     {
-//                                     // we may have to compute
-//                                     // constraints for
-//                                     // vertices. gotta think about
-//                                     // that a bit more
-//
-// //TODO[WB]: think about what to do here...
-//     }
-//#endif
-
-
-
-    template <class DH>
-    void
-    make_oldstyle_hanging_node_constraints (const DH         &dof_handler,
-                                            ConstraintMatrix &constraints,
-                                            dealii::internal::int2type<2>)
-    {
-      const unsigned int dim = 2;
-
-      const unsigned int spacedim = DH::space_dimension;
-
-      std::vector<types::global_dof_index> dofs_on_mother;
-      std::vector<types::global_dof_index> dofs_on_children;
-
-      // loop over all lines; only on lines there can be constraints. We do
-      // so by looping over all active cells and checking whether any of
-      // the faces are refined which can only be from the neighboring cell
-      // because this one is active. In that case, the face is subject to
-      // constraints
-      //
-      // note that even though we may visit a face twice if the neighboring
-      // cells are equally refined, we can only visit each face with
-      // hanging nodes once
-      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
-                                        endc = dof_handler.end();
-      for (; cell!=endc; ++cell)
-        // artificial cells can at best neighbor ghost cells, but we're not
-        // interested in these interfaces
-        if (!cell->is_artificial ())
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-            if (cell->face(face)->has_children())
-              {
-                // in any case, faces can have at most two active fe
-                // indices, but here the face can have only one (namely the
-                // same as that from the cell we're sitting on), and each
-                // of the children can have only one as well. check this
-                Assert (cell->face(face)->n_active_fe_indices() == 1,
-                        ExcInternalError());
-                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
-                        == true,
-                        ExcInternalError());
-                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
-                    Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
-                            ExcInternalError());
-
-                // right now, all that is implemented is the case that both
-                // sides use the same fe
-                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
-                    Assert (cell->face(face)->child(c)
-                            ->fe_index_is_active(cell->active_fe_index()) == true,
-                            ExcNotImplemented());
-
-                // ok, start up the work
-                const FiniteElement<dim,spacedim> &fe       = cell->get_fe();
-                const unsigned int        fe_index = cell->active_fe_index();
-
-                const unsigned int
-                n_dofs_on_mother   = 2*fe.dofs_per_vertex + fe.dofs_per_line,
-                n_dofs_on_children = fe.dofs_per_vertex + 2*fe.dofs_per_line;
-
-                dofs_on_mother.resize (n_dofs_on_mother);
-                dofs_on_children.resize (n_dofs_on_children);
-
-                Assert(n_dofs_on_mother == fe.constraints().n(),
-                       ExcDimensionMismatch(n_dofs_on_mother,
-                                            fe.constraints().n()));
-                Assert(n_dofs_on_children == fe.constraints().m(),
-                       ExcDimensionMismatch(n_dofs_on_children,
-                                            fe.constraints().m()));
-
-                const typename DH::line_iterator this_face = cell->face(face);
-
-                // fill the dofs indices. Use same enumeration scheme as in
-                // @p{FiniteElement::constraints()}
-                unsigned int next_index = 0;
-                for (unsigned int vertex=0; vertex<2; ++vertex)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-                    dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
-                                                                               fe_index);
-                for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-                  dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
-                AssertDimension (next_index, dofs_on_mother.size());
-
-                next_index = 0;
-                for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(0)->vertex_dof_index(1,dof,fe_index);
-                for (unsigned int child=0; child<2; ++child)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-                    dofs_on_children[next_index++]
-                      = this_face->child(child)->dof_index(dof, fe_index);
-                AssertDimension (next_index, dofs_on_children.size());
-
-                // for each row in the constraint matrix for this line:
-                for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
-                  {
-                    constraints.add_line (dofs_on_children[row]);
-                    for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
-                      constraints.add_entry (dofs_on_children[row],
-                                             dofs_on_mother[i],
-                                             fe.constraints()(row,i));
-
-                    constraints.set_inhomogeneity (dofs_on_children[row], 0.);
-                  }
-              }
-            else
-              {
-                // this face has no children, but it could still be that it
-                // is shared by two cells that use a different fe index.
-                // check a couple of things, but ignore the case that the
-                // neighbor is an artificial cell
-                if (!cell->at_boundary(face) &&
-                    !cell->neighbor(face)->is_artificial())
-                  {
-                    Assert (cell->face(face)->n_active_fe_indices() == 1,
-                            ExcNotImplemented());
-                    Assert (cell->face(face)
-                            ->fe_index_is_active(cell->active_fe_index()) == true,
-                            ExcInternalError());
-                  }
-              }
-    }
-
-
-
-    template <class DH>
-    void
-    make_oldstyle_hanging_node_constraints (const DH         &dof_handler,
-                                            ConstraintMatrix &constraints,
-                                            dealii::internal::int2type<3>)
-    {
-      const unsigned int dim = 3;
-
-      std::vector<types::global_dof_index> dofs_on_mother;
-      std::vector<types::global_dof_index> dofs_on_children;
-
-      // loop over all quads; only on quads there can be constraints. We do
-      // so by looping over all active cells and checking whether any of
-      // the faces are refined which can only be from the neighboring cell
-      // because this one is active. In that case, the face is subject to
-      // constraints
-      //
-      // note that even though we may visit a face twice if the neighboring
-      // cells are equally refined, we can only visit each face with
-      // hanging nodes once
-      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
-                                        endc = dof_handler.end();
-      for (; cell!=endc; ++cell)
-        // artificial cells can at best neighbor ghost cells, but we're not
-        // interested in these interfaces
-        if (!cell->is_artificial ())
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-            if (cell->face(face)->has_children())
-              {
-                // first of all, make sure that we treat a case which is
-                // possible, i.e. either no dofs on the face at all or no
-                // anisotropic refinement
-                if (cell->get_fe().dofs_per_face == 0)
-                  continue;
-
-                Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
-                       ExcNotImplemented());
-
-                // in any case, faces can have at most two active fe
-                // indices, but here the face can have only one (namely the
-                // same as that from the cell we're sitting on), and each
-                // of the children can have only one as well. check this
-                AssertDimension (cell->face(face)->n_active_fe_indices(), 1);
-                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
-                        == true,
-                        ExcInternalError());
-                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                  AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
-
-                // right now, all that is implemented is the case that both
-                // sides use the same fe, and not only that but also that
-                // all lines bounding this face and the children have the
-                // same fe
-                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
-                    {
-                      Assert (cell->face(face)->child(c)
-                              ->fe_index_is_active(cell->active_fe_index()) == true,
-                              ExcNotImplemented());
-                      for (unsigned int e=0; e<4; ++e)
-                        {
-                          Assert (cell->face(face)->child(c)->line(e)
-                                  ->n_active_fe_indices() == 1,
-                                  ExcNotImplemented());
-                          Assert (cell->face(face)->child(c)->line(e)
-                                  ->fe_index_is_active(cell->active_fe_index()) == true,
-                                  ExcNotImplemented());
-                        }
-                    }
-                for (unsigned int e=0; e<4; ++e)
-                  {
-                    Assert (cell->face(face)->line(e)
-                            ->n_active_fe_indices() == 1,
-                            ExcNotImplemented());
-                    Assert (cell->face(face)->line(e)
-                            ->fe_index_is_active(cell->active_fe_index()) == true,
-                            ExcNotImplemented());
-                  }
-
-                // ok, start up the work
-                const FiniteElement<dim> &fe       = cell->get_fe();
-                const unsigned int        fe_index = cell->active_fe_index();
-
-                const unsigned int n_dofs_on_mother = fe.dofs_per_face;
-                const unsigned int n_dofs_on_children = (5*fe.dofs_per_vertex+
-                                                         12*fe.dofs_per_line+
-                                                         4*fe.dofs_per_quad);
-
-                //TODO[TL]: think about this and the following in case of anisotropic refinement
-
-                dofs_on_mother.resize (n_dofs_on_mother);
-                dofs_on_children.resize (n_dofs_on_children);
-
-                Assert(n_dofs_on_mother == fe.constraints().n(),
-                       ExcDimensionMismatch(n_dofs_on_mother,
-                                            fe.constraints().n()));
-                Assert(n_dofs_on_children == fe.constraints().m(),
-                       ExcDimensionMismatch(n_dofs_on_children,
-                                            fe.constraints().m()));
-
-                const typename DH::face_iterator this_face = cell->face(face);
-
-                // fill the dofs indices. Use same enumeration scheme as in
-                // @p{FiniteElement::constraints()}
-                unsigned int next_index = 0;
-                for (unsigned int vertex=0; vertex<4; ++vertex)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-                    dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
-                                                                               fe_index);
-                for (unsigned int line=0; line<4; ++line)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-                    dofs_on_mother[next_index++]
-                      = this_face->line(line)->dof_index(dof, fe_index);
-                for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
-                  dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
-                AssertDimension (next_index, dofs_on_mother.size());
-
-                next_index = 0;
-
-                // assert some consistency assumptions
-
-                //TODO[TL]: think about this in case of anisotropic
-                //refinement
-
-                Assert (dof_handler.get_tria().get_anisotropic_refinement_flag() ||
-                        ((this_face->child(0)->vertex_index(3) ==
-                          this_face->child(1)->vertex_index(2)) &&
-                         (this_face->child(0)->vertex_index(3) ==
-                          this_face->child(2)->vertex_index(1)) &&
-                         (this_face->child(0)->vertex_index(3) ==
-                          this_face->child(3)->vertex_index(0))),
-                        ExcInternalError());
-                for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(0)->vertex_dof_index(3,dof);
-
-                // dof numbers on the centers of the lines bounding this
-                // face
-                for (unsigned int line=0; line<4; ++line)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
-                    dofs_on_children[next_index++]
-                      = this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index);
-
-                // next the dofs on the lines interior to the face; the
-                // order of these lines is laid down in the FiniteElement
-                // class documentation
-                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(0)->line(1)->dof_index(dof, fe_index);
-                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(2)->line(1)->dof_index(dof, fe_index);
-                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(0)->line(3)->dof_index(dof, fe_index);
-                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
-                  dofs_on_children[next_index++]
-                    = this_face->child(1)->line(3)->dof_index(dof, fe_index);
-
-                // dofs on the bordering lines
-                for (unsigned int line=0; line<4; ++line)
-                  for (unsigned int child=0; child<2; ++child)
-                    for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
-                      dofs_on_children[next_index++]
-                        = this_face->line(line)->child(child)->dof_index(dof, fe_index);
-
-                // finally, for the dofs interior to the four child faces
-                for (unsigned int child=0; child<4; ++child)
-                  for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
-                    dofs_on_children[next_index++]
-                      = this_face->child(child)->dof_index(dof, fe_index);
-                AssertDimension (next_index, dofs_on_children.size());
-
-                // for each row in the constraint matrix for this line:
-                for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
-                  {
-                    constraints.add_line (dofs_on_children[row]);
-                    for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
-                      constraints.add_entry (dofs_on_children[row],
-                                             dofs_on_mother[i],
-                                             fe.constraints()(row,i));
-
-                    constraints.set_inhomogeneity(dofs_on_children[row], 0.);
-                  }
-              }
-            else
-              {
-                // this face has no children, but it could still be that it
-                // is shared by two cells that use a different fe index.
-                // check a couple of things, but ignore the case that the
-                // neighbor is an artificial cell
-                if (!cell->at_boundary(face) &&
-                    !cell->neighbor(face)->is_artificial())
-                  {
-                    Assert (cell->face(face)->n_active_fe_indices() == 1,
-                            ExcNotImplemented());
-                    Assert (cell->face(face)
-                            ->fe_index_is_active(cell->active_fe_index()) == true,
-                            ExcInternalError());
-                  }
-              }
-    }
-
-
-    template <class DH>
-    void
-    make_hp_hanging_node_constraints (const DH         &dof_handler,
-                                      ConstraintMatrix &constraints)
-    {
-      // note: this function is going to be hard to understand if you
-      // haven't read the hp paper. however, we try to follow the notation
-      // laid out there, so go read the paper before you try to understand
-      // what is going on here
-
-      const unsigned int dim = DH::dimension;
-
-      const unsigned int spacedim = DH::space_dimension;
-
-
-      // a matrix to be used for constraints below. declared here and
-      // simply resized down below to avoid permanent re-allocation of
-      // memory
-      FullMatrix<double> constraint_matrix;
-
-      // similarly have arrays that will hold master and slave dof numbers,
-      // as well as a scratch array needed for the complicated case below
-      std::vector<types::global_dof_index> master_dofs;
-      std::vector<types::global_dof_index> slave_dofs;
-      std::vector<types::global_dof_index> scratch_dofs;
-
-      // caches for the face and subface interpolation matrices between
-      // different (or the same) finite elements. we compute them only
-      // once, namely the first time they are needed, and then just reuse
-      // them
-      Table<2,std_cxx1x::shared_ptr<FullMatrix<double> > >
-      face_interpolation_matrices (n_finite_elements (dof_handler),
-                                   n_finite_elements (dof_handler));
-      Table<3,std_cxx1x::shared_ptr<FullMatrix<double> > >
-      subface_interpolation_matrices (n_finite_elements (dof_handler),
-                                      n_finite_elements (dof_handler),
-                                      GeometryInfo<dim>::max_children_per_face);
-
-      // similarly have a cache for the matrices that are split into their
-      // master and slave parts, and for which the master part is inverted.
-      // these two matrices are derived from the face interpolation matrix
-      // as described in the @ref hp_paper "hp paper"
-      Table<2,std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > >
-      split_face_interpolation_matrices (n_finite_elements (dof_handler),
-                                         n_finite_elements (dof_handler));
-
-      // finally, for each pair of finite elements, have a mask that states
-      // which of the degrees of freedom on the coarse side of a refined
-      // face will act as master dofs.
-      Table<2,std_cxx1x::shared_ptr<std::vector<bool> > >
-      master_dof_masks (n_finite_elements (dof_handler),
-                        n_finite_elements (dof_handler));
-
-      // loop over all faces
-      //
-      // note that even though we may visit a face twice if the neighboring
-      // cells are equally refined, we can only visit each face with
-      // hanging nodes once
-      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
-                                        endc = dof_handler.end();
-      for (; cell!=endc; ++cell)
-        // artificial cells can at best neighbor ghost cells, but we're not
-        // interested in these interfaces
-        if (!cell->is_artificial ())
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-            if (cell->face(face)->has_children())
-              {
-                // first of all, make sure that we treat a case which is
-                // possible, i.e. either no dofs on the face at all or no
-                // anisotropic refinement
-                if (cell->get_fe().dofs_per_face == 0)
-                  continue;
-
-                Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
-                       ExcNotImplemented());
-
-                // so now we've found a face of an active cell that has
-                // children. that means that there are hanging nodes here.
-
-                // in any case, faces can have at most two sets of active
-                // fe indices, but here the face can have only one (namely
-                // the same as that from the cell we're sitting on), and
-                // each of the children can have only one as well. check
-                // this
-                Assert (cell->face(face)->n_active_fe_indices() == 1,
-                        ExcInternalError());
-                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
-                        == true,
-                        ExcInternalError());
-                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                  Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
-                          ExcInternalError());
-
-                // first find out whether we can constrain each of the
-                // subfaces to the mother face. in the lingo of the hp
-                // paper, this would be the simple case. note that we can
-                // short-circuit this decision if the dof_handler doesn't
-                // support hp at all
-                //
-                // ignore all interfaces with artificial cells
-                FiniteElementDomination::Domination
-                mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
-
-                if (DoFHandlerSupportsDifferentFEs<DH>::value == true)
-                  for (unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
-                    if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
-                      mother_face_dominates = mother_face_dominates &
-                                              (cell->get_fe().compare_for_face_domination
-                                               (cell->neighbor_child_on_subface (face, c)->get_fe()));
-
-                switch (mother_face_dominates)
-                  {
-                  case FiniteElementDomination::this_element_dominates:
-                  case FiniteElementDomination::either_element_can_dominate:
-                  {
-                    // Case 1 (the simple case and the only case that can
-                    // happen for non-hp DoFHandlers): The coarse element
-                    // dominates the elements on the subfaces (or they are
-                    // all the same)
-                    //
-                    // so we are going to constrain the DoFs on the face
-                    // children against the DoFs on the face itself
-                    master_dofs.resize (cell->get_fe().dofs_per_face);
-
-                    cell->face(face)->get_dof_indices (master_dofs,
-                                                       cell->active_fe_index ());
-
-                    // Now create constraint matrix for the subfaces and
-                    // assemble it. ignore all interfaces with artificial
-                    // cells because we can only get to such interfaces if
-                    // the current cell is a ghost cell
-                    for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
-                      {
-                        if (cell->neighbor_child_on_subface (face, c)->is_artificial())
-                          continue;
-
-                        const typename DH::active_face_iterator
-                        subface = cell->face(face)->child(c);
-
-                        Assert (subface->n_active_fe_indices() == 1,
-                                ExcInternalError());
-
-                        const unsigned int
-                        subface_fe_index = subface->nth_active_fe_index(0);
-
-                        // we sometime run into the situation where for
-                        // example on one big cell we have a FE_Q(1) and on
-                        // the subfaces we have a mixture of FE_Q(1) and
-                        // FE_Nothing. In that case, the face domination is
-                        // either_element_can_dominate for the whole
-                        // collection of subfaces, but on the particular
-                        // subface between FE_Q(1) and FE_Nothing, there
-                        // are no constraints that we need to take care of.
-                        // in that case, just continue
-                        if (cell->get_fe().compare_for_face_domination
-                            (subface->get_fe(subface_fe_index))
-                            ==
-                            FiniteElementDomination::no_requirements)
-                          continue;
-
-                        // Same procedure as for the mother cell. Extract
-                        // the face DoFs from the cell DoFs.
-                        slave_dofs.resize (subface->get_fe(subface_fe_index)
-                                           .dofs_per_face);
-                        subface->get_dof_indices (slave_dofs, subface_fe_index);
-
-                        for (unsigned int i=0; i<slave_dofs.size(); ++i)
-                          Assert (slave_dofs[i] != numbers::invalid_dof_index,
-                                  ExcInternalError());
-
-                        // Now create the element constraint for this
-                        // subface.
-                        //
-                        // As a side remark, one may wonder the following:
-                        // neighbor_child is clearly computed correctly,
-                        // i.e. taking into account face_orientation (just
-                        // look at the implementation of that function).
-                        // however, we don't care about this here, when we
-                        // ask for subface_interpolation on subface c. the
-                        // question rather is: do we have to translate 'c'
-                        // here as well?
-                        //
-                        // the answer is in fact 'no'. if one does that,
-                        // results are wrong: constraints are added twice
-                        // for the same pair of nodes but with differing
-                        // weights. in addition, one can look at the
-                        // deal.II/project_*_03 tests that look at exactly
-                        // this case: there, we have a mesh with at least
-                        // one face_orientation==false and hanging nodes,
-                        // and the results of those tests show that the
-                        // result of projection verifies the approximation
-                        // properties of a finite element onto that mesh
-                        ensure_existence_of_subface_matrix
-                        (cell->get_fe(),
-                         subface->get_fe(subface_fe_index),
-                         c,
-                         subface_interpolation_matrices
-                         [cell->active_fe_index()][subface_fe_index][c]);
-
-                        // Add constraints to global constraint matrix.
-                        filter_constraints (master_dofs,
-                                            slave_dofs,
-                                            *(subface_interpolation_matrices
-                                              [cell->active_fe_index()][subface_fe_index][c]),
-                                            constraints);
-                      }
-
-                    break;
-                  }
-
-                  case FiniteElementDomination::other_element_dominates:
-                  case FiniteElementDomination::neither_element_dominates:
-                  {
-                    // Case 2 (the "complex" case): at least one (the
-                    // neither_... case) of the finer elements or all of
-                    // them (the other_... case) is dominating. See the hp
-                    // paper for a way how to deal with this situation
-                    //
-                    // since this is something that can only happen for hp
-                    // dof handlers, add a check here...
-                    Assert (DoFHandlerSupportsDifferentFEs<DH>::value == true,
-                            ExcInternalError());
-
-                    // we first have to find the finite element that is
-                    // able to generate a space that all the other ones can
-                    // be constrained to
-                    const unsigned int dominating_fe_index
-                      = get_most_dominating_subface_fe_index (cell->face(face));
-
-                    const FiniteElement<dim,spacedim> &dominating_fe
-                      = dof_handler.get_fe()[dominating_fe_index];
-
-                    // check also that it is able to constrain the mother
-                    // face. it should be, or we wouldn't have gotten into
-                    // the branch for the 'complex' case
-                    Assert ((dominating_fe.compare_for_face_domination
-                             (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
-                             == FiniteElementDomination::this_element_dominates)
-                            ||
-                            (dominating_fe.compare_for_face_domination
-                             (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
-                             == FiniteElementDomination::either_element_can_dominate),
-                            ExcInternalError());
-
-
-                    // first get the interpolation matrix from the mother
-                    // to the virtual dofs
-                    Assert (dominating_fe.dofs_per_face <=
-                            cell->get_fe().dofs_per_face,
-                            ExcInternalError());
-
-                    ensure_existence_of_face_matrix
-                    (dominating_fe,
-                     cell->get_fe(),
-                     face_interpolation_matrices
-                     [dominating_fe_index][cell->active_fe_index()]);
-
-                    // split this matrix into master and slave components.
-                    // invert the master component
-                    ensure_existence_of_master_dof_mask
-                    (cell->get_fe(),
-                     dominating_fe,
-                     (*face_interpolation_matrices
-                      [dominating_fe_index]
-                      [cell->active_fe_index()]),
-                     master_dof_masks
-                     [dominating_fe_index]
-                     [cell->active_fe_index()]);
-
-                    ensure_existence_of_split_face_matrix
-                    (*face_interpolation_matrices
-                     [dominating_fe_index][cell->active_fe_index()],
-                     (*master_dof_masks
-                      [dominating_fe_index][cell->active_fe_index()]),
-                     split_face_interpolation_matrices
-                     [dominating_fe_index][cell->active_fe_index()]);
-
-                    const FullMatrix<double> &restrict_mother_to_virtual_master_inv
-                      = (split_face_interpolation_matrices
-                         [dominating_fe_index][cell->active_fe_index()]->first);
-
-                    const FullMatrix<double> &restrict_mother_to_virtual_slave
-                      = (split_face_interpolation_matrices
-                         [dominating_fe_index][cell->active_fe_index()]->second);
-
-                    // now compute the constraint matrix as the product
-                    // between the inverse matrix and the slave part
-                    constraint_matrix.reinit (cell->get_fe().dofs_per_face -
-                                              dominating_fe.dofs_per_face,
-                                              dominating_fe.dofs_per_face);
-                    restrict_mother_to_virtual_slave
-                    .mmult (constraint_matrix,
-                            restrict_mother_to_virtual_master_inv);
-
-                    // then figure out the global numbers of master and
-                    // slave dofs and apply constraints
-                    scratch_dofs.resize (cell->get_fe().dofs_per_face);
-                    cell->face(face)->get_dof_indices (scratch_dofs,
-                                                       cell->active_fe_index ());
-
-                    // split dofs into master and slave components
-                    master_dofs.clear ();
-                    slave_dofs.clear ();
-                    for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
-                      if ((*master_dof_masks
-                           [dominating_fe_index][cell->active_fe_index()])[i] == true)
-                        master_dofs.push_back (scratch_dofs[i]);
-                      else
-                        slave_dofs.push_back (scratch_dofs[i]);
-
-                    AssertDimension (master_dofs.size(), dominating_fe.dofs_per_face);
-                    AssertDimension (slave_dofs.size(),
-                                     cell->get_fe().dofs_per_face - dominating_fe.dofs_per_face);
-
-                    filter_constraints (master_dofs,
-                                        slave_dofs,
-                                        constraint_matrix,
-                                        constraints);
-
-
-
-                    // next we have to deal with the subfaces. do as
-                    // discussed in the hp paper
-                    for (unsigned int sf=0;
-                         sf<cell->face(face)->n_children(); ++sf)
-                      {
-                        // ignore interfaces with artificial cells as well
-                        // as interfaces between ghost cells in 2d
-                        if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
-                            ||
-                            (dim==2 && cell->is_ghost()
-                             &&
-                             cell->neighbor_child_on_subface (face, sf)->is_ghost()))
-                          continue;
-
-                        Assert (cell->face(face)->child(sf)
-                                ->n_active_fe_indices() == 1,
-                                ExcInternalError());
-
-                        const unsigned int subface_fe_index
-                          = cell->face(face)->child(sf)->nth_active_fe_index(0);
-                        const FiniteElement<dim,spacedim> &subface_fe
-                          = dof_handler.get_fe()[subface_fe_index];
-
-                        // first get the interpolation matrix from the
-                        // subface to the virtual dofs
-                        Assert (dominating_fe.dofs_per_face <=
-                                subface_fe.dofs_per_face,
-                                ExcInternalError());
-                        ensure_existence_of_subface_matrix
-                        (dominating_fe,
-                         subface_fe,
-                         sf,
-                         subface_interpolation_matrices
-                         [dominating_fe_index][subface_fe_index][sf]);
-
-                        const FullMatrix<double> &restrict_subface_to_virtual
-                          = *(subface_interpolation_matrices
-                              [dominating_fe_index][subface_fe_index][sf]);
-
-                        constraint_matrix.reinit (subface_fe.dofs_per_face,
-                                                  dominating_fe.dofs_per_face);
-
-                        restrict_subface_to_virtual
-                        .mmult (constraint_matrix,
-                                restrict_mother_to_virtual_master_inv);
-
-                        slave_dofs.resize (subface_fe.dofs_per_face);
-                        cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
-                                                                      subface_fe_index);
-
-                        filter_constraints (master_dofs,
-                                            slave_dofs,
-                                            constraint_matrix,
-                                            constraints);
-                      }
-
-                    break;
-                  }
-
-                  case FiniteElementDomination::no_requirements:
-                    // there are no continuity requirements between the two
-                    // elements. record no constraints
-                    break;
-
-                  default:
-                    // we shouldn't get here
-                    Assert (false, ExcInternalError());
-                  }
-              }
-            else
-              {
-                // this face has no children, but it could still be that it
-                // is shared by two cells that use a different fe index
-                Assert (cell->face(face)
-                        ->fe_index_is_active(cell->active_fe_index()) == true,
-                        ExcInternalError());
-
-                // see if there is a neighbor that is an artificial cell.
-                // in that case, we're not interested in this interface. we
-                // test this case first since artificial cells may not have
-                // an active_fe_index set, etc
-                if (!cell->at_boundary(face)
-                    &&
-                    cell->neighbor(face)->is_artificial())
-                  continue;
-
-                // Only if there is a neighbor with a different
-                // active_fe_index and the same h-level, some action has to
-                // be taken.
-                if ((DoFHandlerSupportsDifferentFEs<DH>::value == true)
-                    &&
-                    !cell->face(face)->at_boundary ()
-                    &&
-                    (cell->neighbor(face)->active_fe_index () !=
-                     cell->active_fe_index ())
-                    &&
-                    (!cell->face(face)->has_children() &&
-                     !cell->neighbor_is_coarser(face) ))
-                  {
-                    const typename DH::level_cell_iterator neighbor = cell->neighbor (face);
-
-                    // see which side of the face we have to constrain
-                    switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
-                      {
-                      case FiniteElementDomination::this_element_dominates:
-                      {
-                        // Get DoFs on dominating and dominated side of the
-                        // face
-                        master_dofs.resize (cell->get_fe().dofs_per_face);
-                        cell->face(face)->get_dof_indices (master_dofs,
-                                                           cell->active_fe_index ());
-
-                        slave_dofs.resize (neighbor->get_fe().dofs_per_face);
-                        cell->face(face)->get_dof_indices (slave_dofs,
-                                                           neighbor->active_fe_index ());
-
-                        // break if the n_master_dofs == 0, because we are
-                        // attempting to constrain to an element that has
-                        // no face dofs
-                        if (master_dofs.size() == 0) break;
-
-                        // make sure the element constraints for this face
-                        // are available
-                        ensure_existence_of_face_matrix
-                        (cell->get_fe(),
-                         neighbor->get_fe(),
-                         face_interpolation_matrices
-                         [cell->active_fe_index()][neighbor->active_fe_index()]);
-
-                        // Add constraints to global constraint matrix.
-                        filter_constraints (master_dofs,
-                                            slave_dofs,
-                                            *(face_interpolation_matrices
-                                              [cell->active_fe_index()]
-                                              [neighbor->active_fe_index()]),
-                                            constraints);
-
-                        break;
-                      }
-
-                      case FiniteElementDomination::other_element_dominates:
-                      {
-                        // we don't do anything here since we will come
-                        // back to this face from the other cell, at which
-                        // time we will fall into the first case clause
-                        // above
-                        break;
-                      }
-
-                      case FiniteElementDomination::either_element_can_dominate:
-                      {
-                        // it appears as if neither element has any
-                        // constraints on its neighbor. this may be because
-                        // neither element has any DoFs on faces at all. or
-                        // that the two elements are actually the same,
-                        // although they happen to run under different
-                        // fe_indices (this is what happens in
-                        // hp/hp_hanging_nodes_01 for example).
-                        //
-                        // another possibility is what happens in crash_13.
-                        // there, we have FESystem(FE_Q(1),FE_DGQ(0)) vs.
-                        // FESystem(FE_Q(1),FE_DGQ(1)). neither of them
-                        // dominates the other.
-                       //
-                       // a final possibility is that we have something like
-                       // FESystem(FE_Q(1),FE_Q(1)) vs
-                       // FESystem(FE_Q(1),FE_Nothing()), see
-                       // hp/fe_nothing_18/19.
-                       //
-                       // in any case, the point is that it doesn't
-                        // matter. there is nothing to do here.
-                        break;
-                      }
-
-                      case FiniteElementDomination::neither_element_dominates:
-                      {
-                        // we don't presently know what exactly to do here.
-                        // it isn't quite clear what exactly we would have
-                        // to do here. sit tight until someone trips over
-                        // the following statement and see what exactly is
-                        // going on
-                        Assert (false, ExcNotImplemented());
-                        break;
-                      }
-
-                      case FiniteElementDomination::no_requirements:
-                      {
-                        // nothing to do here
-                        break;
-                      }
-
-                      default:
-                        // we shouldn't get here
-                        Assert (false, ExcInternalError());
-                      }
-                  }
-              }
-    }
-  }
-
-
-
-
-  template <class DH>
-  void
-  make_hanging_node_constraints (const DH &dof_handler,
-                                 ConstraintMatrix &constraints)
-  {
-    // Decide whether to use the new or old make_hanging_node_constraints
-    // function. If all the FiniteElement or all elements in a FECollection
-    // support the new face constraint matrix, the new code will be used.
-    // Otherwise, the old implementation is used for the moment.
-    if (dof_handler.get_fe().hp_constraints_are_implemented ())
-      internal::
-      make_hp_hanging_node_constraints (dof_handler,
-                                        constraints);
-    else
-      internal::
-      make_oldstyle_hanging_node_constraints (dof_handler,
-                                              constraints,
-                                              dealii::internal::int2type<DH::dimension>());
-  }
-
-
-
-  namespace
-  {
-    // enter constraints for periodicity into the given ConstraintMatrix object.
-    // this function is called when at least one of the two face iterators corresponds
-    // to an active object without further children
-    //
-    // @param transformation A matrix that maps degrees of freedom from one face
-    // to another. If the DoFs on the two faces are supposed to match exactly, then
-    // the matrix so provided will be the identity matrix. if face 2 is once refined
-    // from face 1, then the matrix needs to be the interpolation matrix from a face
-    // to this particular child
-    //
-    // @precondition: face_1 is supposed to be active
-    //
-    // @note As bug #82 ((http://code.google.com/p/dealii/issues/detail?id=82) and the
-    // corresponding testcase bits/periodicity_05 demonstrate, we can occasionally
-    // get into trouble if we already have the constraint x1=x2 and want to insert
-    // x2=x1. we avoid this by skipping an identity constraint if the opposite
-    // constraint already exists
-    template <typename FaceIterator>
-    void
-    set_periodicity_constraints (const FaceIterator                          &face_1,
-                                 const typename identity<FaceIterator>::type &face_2,
-                                 const FullMatrix<double>                    &transformation,
-                                 dealii::ConstraintMatrix                    &constraint_matrix,
-                                 const ComponentMask                         &component_mask,
-                                 const bool                                   face_orientation,
-                                 const bool                                   face_flip,
-                                 const bool                                   face_rotation)
-    {
-      static const int dim      = FaceIterator::AccessorType::dimension;
-      static const int spacedim = FaceIterator::AccessorType::space_dimension;
-
-      // we should be in the case where face_1 is active, i.e. has no children:
-      Assert (!face_1->has_children(),
-              ExcInternalError());
-
-      Assert (face_1->n_active_fe_indices() == 1,
-              ExcInternalError());
-
-      // if face_2 does have children, then we need to iterate over them
-      if (face_2->has_children())
-        {
-          Assert (face_2->n_children() == GeometryInfo<dim>::max_children_per_face,
-                  ExcNotImplemented());
-          const unsigned int dofs_per_face
-            = face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
-          FullMatrix<double> child_transformation (dofs_per_face, dofs_per_face);
-          FullMatrix<double> subface_interpolation (dofs_per_face, dofs_per_face);
-          for (unsigned int c=0; c<face_2->n_children(); ++c)
-            {
-              // get the interpolation matrix recursively from the one that
-              // interpolated from face_1 to face_2 by multiplying from the
-              // left with the one that interpolates from face_2 to
-              // its child
-              face_1->get_fe(face_1->nth_active_fe_index(0))
-              .get_subface_interpolation_matrix (face_1->get_fe(face_1->nth_active_fe_index(0)),
-                                                 c,
-                                                 subface_interpolation);
-              subface_interpolation.mmult (child_transformation, transformation);
-              set_periodicity_constraints(face_1, face_2->child(c),
-                                          child_transformation,
-                                          constraint_matrix, component_mask,
-                                          face_orientation, face_flip, face_rotation);
-            }
-        }
-      else
-        // both faces are active. we need to match the corresponding DoFs of both faces
-        {
-          const unsigned int face_1_index = face_1->nth_active_fe_index(0);
-          const unsigned int face_2_index = face_2->nth_active_fe_index(0);
-          Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_1_index),
-                 ExcMessage ("Matching periodic cells need to use the same finite element"));
-
-          const FiniteElement<dim, spacedim> &fe = face_1->get_fe(face_1_index);
-
-          Assert(component_mask.represents_n_components(fe.n_components()),
-                 ExcMessage ("The number of components in the mask has to be either "
-                             "zero or equal to the number of components in the finite " "element."));
-
-          const unsigned int dofs_per_face = fe.dofs_per_face;
-
-          std::vector<types::global_dof_index> dofs_1(dofs_per_face);
-          std::vector<types::global_dof_index> dofs_2(dofs_per_face);
-
-          face_1->get_dof_indices(dofs_1, face_1_index);
-          face_2->get_dof_indices(dofs_2, face_2_index);
-
-          // Well, this is a hack:
-          //
-          // There is no
-          //   face_to_face_index(face_index,
-          //                      face_orientation,
-          //                      face_flip,
-          //                      face_rotation)
-          // function in FiniteElementData, so we have to use
-          //   face_to_cell_index(face_index, face
-          //                      face_orientation,
-          //                      face_flip,
-          //                      face_rotation)
-          // But this will give us an index on a cell - something we cannot work
-          // with directly. But luckily we can match them back :-]
-
-          std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
-
-          // Build up a cell to face index for face_2:
-          for (unsigned int i = 0; i < dofs_per_face; ++i)
-            {
-              const unsigned int cell_index = fe.face_to_cell_index(i, 0, /* It doesn't really matter, just assume
-                                                                           * we're on the first face...
-                                                                           */
-                                                                    true, false, false // default orientation
-                                                                   );
-              cell_to_rotated_face_index[cell_index] = i;
-            }
-
-          // loop over all dofs on face 2 and constrain them again the ones on face 1
-          for (unsigned int i=0; i<dofs_per_face; ++i)
-            if (!constraint_matrix.is_constrained(dofs_2[i]))
-              if ((component_mask.n_selected_components(fe.n_components())
-                   == fe.n_components())
-                  ||
-                  component_mask[fe.face_system_to_component_index(i).first])
-                {
-                  // as mentioned in the comment above this function, we need
-                  // to be careful about treating identity constraints differently.
-                  // consequently, find out whether this dof 'i' will be
-                  // identity constrained
-                  //
-                  // to check whether this is the case, first see whether there are
-                  // any weights other than 0 and 1, then in a first stage make sure
-                  // that if so there is only one weight equal to 1
-                  bool is_identity_constrained = true;
-                  for (unsigned int jj=0; jj<dofs_per_face; ++jj)
-                    if (((transformation(i,jj) == 0) || (transformation(i,jj) == 1)) == false)
-                      {
-                        is_identity_constrained = false;
-                        break;
-                      }
-                  unsigned int identity_constraint_target = numbers::invalid_unsigned_int;
-                  if (is_identity_constrained == true)
-                    {
-                      bool one_identity_found = false;
-                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
-                        if (transformation(i,jj) == 1)
-                          {
-                            if (one_identity_found == false)
-                              {
-                                one_identity_found = true;
-                                identity_constraint_target = jj;
-                              }
-                            else
-                              {
-                                is_identity_constrained = false;
-                                identity_constraint_target = numbers::invalid_unsigned_int;
-                                break;
-                              }
-                          }
-                    }
-
-                  // now treat constraints, either as an equality constraint or
-                  // as a sequence of constraints
-                  if (is_identity_constrained == true)
-                    {
-                      // Query the correct face_index on face_2 respecting the given
-                      // orientation:
-                      const unsigned int j =
-                        cell_to_rotated_face_index[fe.face_to_cell_index(identity_constraint_target,
-                            0, /* It doesn't really matter, just assume
-                           * we're on the first face...
-                           */
-                                                                         face_orientation, face_flip, face_rotation)];
-
-                      // if the two aren't already identity constrained (whichever way
-                      // around, then enter the constraint. otherwise there is nothing
-                      // for us still to do
-                      if (constraint_matrix.are_identity_constrained(dofs_2[i], dofs_1[i]) == false)
-                        {
-                          constraint_matrix.add_line(dofs_2[i]);
-                          constraint_matrix.add_entry(dofs_2[i], dofs_1[j], 1);
-                        }
-                    }
-                  else
-                    {
-                      // this is just a regular constraint. enter it piece by piece
-                      constraint_matrix.add_line(dofs_2[i]);
-                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
-                        {
-                          // Query the correct face_index on face_2 respecting the given
-                          // orientation:
-                          const unsigned int j =
-                            cell_to_rotated_face_index[fe.face_to_cell_index(jj, 0, /* It doesn't really matter, just assume
-                               * we're on the first face...
-                               */
-                                                                             face_orientation, face_flip, face_rotation)];
-
-                          // And finally constrain the two DoFs respecting component_mask:
-                          if (transformation(i,jj) != 0)
-                            constraint_matrix.add_entry(dofs_2[i], dofs_1[j],
-                                                        transformation(i,jj));
-                        }
-                    }
-                }
-        }
-    }
-  }
-
-
-  template <typename FaceIterator>
-  void
-  make_periodicity_constraints (const FaceIterator                          &face_1,
-                                const typename identity<FaceIterator>::type &face_2,
-                                dealii::ConstraintMatrix                    &constraint_matrix,
-                                const ComponentMask                         &component_mask,
-                                const bool                                   face_orientation,
-                                const bool                                   face_flip,
-                                const bool                                   face_rotation)
-  {
-    static const int dim = FaceIterator::AccessorType::dimension;
-
-    Assert( (dim != 1) ||
-            (face_orientation == true &&
-             face_flip == false &&
-             face_rotation == false),
-            ExcMessage ("The supplied orientation "
-                        "(face_orientation, face_flip, face_rotation) "
-                        "is invalid for 1D"));
-
-    Assert( (dim != 2) ||
-            (face_orientation == true &&
-             face_rotation == false),
-            ExcMessage ("The supplied orientation "
-                        "(face_orientation, face_flip, face_rotation) "
-                        "is invalid for 2D"));
-
-    Assert(face_1 != face_2,
-           ExcMessage ("face_1 and face_2 are equal! Cannot constrain DoFs "
-                       "on the very same face"));
-
-    Assert(face_1->at_boundary() && face_2->at_boundary(),
-           ExcMessage ("Faces for periodicity constraints must be on the boundary"));
-
-
-    // A lookup table on how to go through the child faces depending on the
-    // orientation:
-
-    static const int lookup_table_2d[2][2] =
-    {
-      //          flip:
-      {0, 1}, //  false
-      {1, 0}, //  true
-    };
-
-    static const int lookup_table_3d[2][2][2][4] =
-    {
-      //                    orientation flip  rotation
-      { { {0, 2, 1, 3}, //  false       false false
-          {2, 3, 0, 1}, //  false       false true
-        },
-        { {3, 1, 2, 0}, //  false       true  false
-          {1, 0, 3, 2}, //  false       true  true
-        },
-      },
-      { { {0, 1, 2, 3}, //  true        false false
-          {1, 3, 0, 2}, //  true        false true
-        },
-        { {3, 2, 1, 0}, //  true        true  false
-          {2, 0, 3, 1}, //  true        true  true
-        },
-      },
-    };
-
-    // In the case that both faces have children, we loop over all
-    // children and apply make_periodicty_constrains recursively:
-    if (face_1->has_children() && face_2->has_children())
-      {
-        Assert(face_1->n_children() == GeometryInfo<dim>::max_children_per_face &&
-               face_2->n_children() == GeometryInfo<dim>::max_children_per_face,
-               ExcNotImplemented());
-
-        for (unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face; ++i)
-          {
-            // Lookup the index for the second face
-            unsigned int j;
-            switch (dim)
-              {
-              case 2:
-                j = lookup_table_2d[face_flip][i];
-                break;
-              case 3:
-                j = lookup_table_3d[face_orientation][face_flip][face_rotation][i];
-                break;
-              default:
-                AssertThrow(false, ExcNotImplemented());
-              }
-
-            make_periodicity_constraints (face_1->child(i),
-                                          face_2->child(j),
-                                          constraint_matrix,
-                                          component_mask,
-                                          face_orientation,
-                                          face_flip,
-                                          face_rotation);
-          }
-      }
-    else
-      // otherwise at least one of the two faces is active and
-      // we need to enter the constraints
-      {
-        if (face_2->has_children() == false)
-          set_periodicity_constraints(face_2, face_1,
-                                      FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face)),
-                                      constraint_matrix,
-                                      component_mask,
-                                      face_orientation, face_flip, face_rotation);
-        else
-          set_periodicity_constraints(face_1, face_2,
-                                      FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face)),
-                                      constraint_matrix,
-                                      component_mask,
-                                      face_orientation, face_flip, face_rotation);
-      }
-  }
-
-
-
-  template<typename DH>
-  void
-  make_periodicity_constraints (const DH                       &dof_handler,
-                                const types::boundary_id       b_id1,
-                                const types::boundary_id       b_id2,
-                                const int                      direction,
-                                dealii::ConstraintMatrix       &constraint_matrix,
-                                const ComponentMask            &component_mask)
-  {
-    Tensor<1,DH::space_dimension> dummy;
-    make_periodicity_constraints (dof_handler,
-                                  b_id1,
-                                  b_id2,
-                                  direction,
-                                  dummy,
-                                  constraint_matrix,
-                                  component_mask);
-  }
-
-
-
-  template<typename DH>
-  void
-  make_periodicity_constraints (const DH                  &dof_handler,
-                                const types::boundary_id  b_id1,
-                                const types::boundary_id  b_id2,
-                                const int                 direction,
-                                dealii::Tensor<1,DH::space_dimension> &offset,
-                                dealii::ConstraintMatrix  &constraint_matrix,
-                                const ComponentMask       &component_mask)
-  {
-    static const int space_dim = DH::space_dimension;
-    Assert (0<=direction && direction<space_dim,
-            ExcIndexRange (direction, 0, space_dim));
-
-#if defined(DEBUG) && defined(DEAL_II_WITH_P4EST)
-    // Check whether we run on a non parallel mesh or on a
-    // parallel::distributed::Triangulation in serial
-    {
-      typedef parallel::distributed::Triangulation<DH::dimension,DH::space_dimension> PTRIA;
-      const PTRIA *ptria_p = dynamic_cast<const PTRIA *> (&dof_handler.get_tria());
-      Assert ((ptria_p == 0 || Utilities::MPI::n_mpi_processes(ptria_p->get_communicator()) == 1),
-              ExcMessage ("This function can not be used with distributed triangulations."
-                          "See the documentation for more information."));
-    }
-#endif
-
-    Assert (b_id1 != b_id2,
-            ExcMessage ("The boundary indicators b_id1 and b_id2 must be"
-                        "different to denote different boundaries."));
-
-    typedef typename DH::face_iterator FaceIterator;
-    typedef std::map<FaceIterator, std::pair<FaceIterator, std::bitset<3> > > FaceMap;
-
-    // Collect matching periodic cells on the coarsest level:
-    FaceMap matched_cells =
-      GridTools::collect_periodic_face_pairs(dof_handler,
-                                             b_id1, b_id2,
-                                             direction, offset);
-
-    // And apply the low level make_periodicity_constraints function to
-    // every matching pair:
-    for (typename FaceMap::iterator it = matched_cells.begin();
-         it != matched_cells.end(); ++it)
-      {
-        typedef typename DH::face_iterator FaceIterator;
-        const FaceIterator &face_1 = it->first;
-        const FaceIterator &face_2 = it->second.first;
-        const std::bitset<3> &orientation = it->second.second;
-
-        Assert(face_1->at_boundary() && face_2->at_boundary(),
-               ExcInternalError());
-
-        Assert (face_1->boundary_indicator() == b_id1 &&
-                face_2->boundary_indicator() == b_id2,
-                ExcInternalError());
-
-        Assert (face_1 != face_2,
-                ExcInternalError());
-
-        make_periodicity_constraints(face_1,
-                                     face_2,
-                                     constraint_matrix,
-                                     component_mask,
-                                     orientation[0],
-                                     orientation[1],
-                                     orientation[2]);
-      }
-  }
-
-
-
-  template<typename DH>
-  void
-  make_periodicity_constraints (const DH                       &dof_handler,
-                                const types::boundary_id       b_id,
-                                const int                      direction,
-                                dealii::ConstraintMatrix       &constraint_matrix,
-                                const ComponentMask            &component_mask)
-  {
-    Tensor<1,DH::space_dimension> dummy;
-    make_periodicity_constraints (dof_handler,
-                                  b_id,
-                                  direction,
-                                  dummy,
-                                  constraint_matrix,
-                                  component_mask);
-  }
-
-
-
-  template<typename DH>
-  void
-  make_periodicity_constraints (const DH                  &dof_handler,
-                                const types::boundary_id  b_id,
-                                const int                 direction,
-                                dealii::Tensor<1,DH::space_dimension> &offset,
-                                dealii::ConstraintMatrix  &constraint_matrix,
-                                const ComponentMask       &component_mask)
-  {
-    static const int dim = DH::dimension;
-    static const int space_dim = DH::space_dimension;
-
-    Assert (0<=direction && direction<space_dim,
-            ExcIndexRange (direction, 0, space_dim));
-
-    Assert(dim == space_dim,
-           ExcNotImplemented());
-
-#if defined(DEBUG) && defined(DEAL_II_WITH_P4EST)
-    // Check whether we run on a non parallel mesh or on a
-    // parallel::distributed::Triangulation in serial
-    {
-      typedef typename parallel::distributed::Triangulation<DH::dimension,DH::space_dimension> PTRIA;
-      const PTRIA *ptria_p = dynamic_cast<const PTRIA *> (&dof_handler.get_tria());
-      Assert ((ptria_p == 0 || Utilities::MPI::n_mpi_processes(ptria_p->get_communicator()) == 1),
-              ExcMessage ("This function can not be used with distributed triangulations."
-                          "See the documentation for more information."));
-    }
-#endif
-
-    typedef typename DH::face_iterator FaceIterator;
-    typedef std::map<FaceIterator, FaceIterator> FaceMap;
-
-    // Collect matching periodic cells on the coarsest level:
-    FaceMap matched_cells =
-      GridTools::collect_periodic_face_pairs(dof_handler,
-                                             b_id,
-                                             direction, offset);
-
-    // And apply the low level make_periodicity_constraints function to
-    // every matching pair:
-    for (typename FaceMap::iterator it = matched_cells.begin();
-         it != matched_cells.end(); ++it)
-      {
-        typedef typename DH::face_iterator FaceIterator;
-        const FaceIterator &face_1 = it->first;
-        const FaceIterator &face_2 = it->second;
-
-        Assert(face_1->at_boundary() && face_2->at_boundary(),
-               ExcInternalError());
-
-        Assert (face_1->boundary_indicator() == b_id &&
-                face_2->boundary_indicator() == b_id,
-                ExcInternalError());
-
-        Assert (face_1 != face_2,
-                ExcInternalError());
-
-        make_periodicity_constraints(face_1,
-                                     face_2,
-                                     constraint_matrix,
-                                     component_mask
-                                     /* standard orientation */);
-      }
-  }
-
-
-
   namespace internal
   {
     // return an array that for each dof on the reference cell
@@ -4719,677 +1512,6 @@ namespace DoFTools
 
 
 
-
-  namespace internal
-  {
-    namespace
-    {
-      /**
-       * This is a function that is called by the _2 function and that
-       * operates on a range of cells only. It is used to split up the
-       * whole range of cells into chunks which are then worked on in
-       * parallel, if multithreading is available.
-       */
-      template <int dim, int spacedim>
-      void
-      compute_intergrid_weights_3 (
-        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
-        const unsigned int                  coarse_component,
-        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
-        const std::vector<dealii::Vector<double> > &parameter_dofs,
-        const std::vector<types::global_dof_index>             &weight_mapping,
-        std::vector<std::map<types::global_dof_index, float> > &weights,
-        const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &begin,
-        const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &end)
-      {
-        // aliases to the finite elements used by the dof handlers:
-        const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe();
-
-        // for each cell on the parameter grid: find out which degrees of
-        // freedom on the fine grid correspond in which way to the degrees
-        // of freedom on the parameter grid
-        //
-        // since for continuous FEs some dofs exist on more than one cell,
-        // we have to track which ones were already visited. the problem is
-        // that if we visit a dof first on one cell and compute its weight
-        // with respect to some global dofs to be non-zero, and later visit
-        // the dof again on another cell and (since we are on another cell)
-        // recompute the weights with respect to the same dofs as above to
-        // be zero now, we have to preserve them. we therefore overwrite
-        // all weights if they are nonzero and do not enforce zero weights
-        // since that might be only due to the fact that we are on another
-        // cell.
-        //
-        // example:
-        // coarse grid
-        //  |     |     |
-        //  *-----*-----*
-        //  | cell|cell |
-        //  |  1  |  2  |
-        //  |     |     |
-        //  0-----1-----*
-        //
-        // fine grid
-        //  |  |  |  |  |
-        //  *--*--*--*--*
-        //  |  |  |  |  |
-        //  *--*--*--*--*
-        //  |  |  |  |  |
-        //  *--x--y--*--*
-        //
-        // when on cell 1, we compute the weights of dof 'x' to be 1/2 from
-        // parameter dofs 0 and 1, respectively. however, when later we are
-        // on cell 2, we again compute the prolongation of shape function 1
-        // restricted to cell 2 to the globla grid and find that the weight
-        // of global dof 'x' now is zero. however, we should not overwrite
-        // the old value.
-        //
-        // we therefore always only set nonzero values. why adding up is
-        // not useful: dof 'y' would get weight 1 from parameter dof 1 on
-        // both cells 1 and 2, but the correct weight is nevertheless only
-        // 1.
-
-        // vector to hold the representation of a single degree of freedom
-        // on the coarse grid (for the selected fe) on the fine grid
-        const types::global_dof_index n_fine_dofs = weight_mapping.size();
-        dealii::Vector<double> global_parameter_representation (n_fine_dofs);
-
-        typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator cell;
-        std::vector<types::global_dof_index> parameter_dof_indices (coarse_fe.dofs_per_cell);
-
-        for (cell=begin; cell!=end; ++cell)
-          {
-            // get the global indices of the parameter dofs on this
-            // parameter grid cell
-            cell->get_dof_indices (parameter_dof_indices);
-
-            // loop over all dofs on this cell and check whether they are
-            // interesting for us
-            for (unsigned int local_dof=0;
-                 local_dof<coarse_fe.dofs_per_cell;
-                 ++local_dof)
-              if (coarse_fe.system_to_component_index(local_dof).first
-                  ==
-                  coarse_component)
-                {
-                  // the how-many-th parameter is this on this cell?
-                  const unsigned int local_parameter_dof
-                    = coarse_fe.system_to_component_index(local_dof).second;
-
-                  global_parameter_representation = 0;
-
-                  // distribute the representation of
-                  // @p{local_parameter_dof} on the parameter grid cell
-                  // @p{cell} to the global data space
-                  coarse_to_fine_grid_map[cell]->
-                  set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
-                                                   global_parameter_representation);
-                  // now that we've got the global representation of each
-                  // parameter dof, we've only got to clobber the non-zero
-                  // entries in that vector and store the result
-                  //
-                  // what we have learned: if entry @p{i} of the global
-                  // vector holds the value @p{v[i]}, then this is the
-                  // weight with which the present dof contributes to
-                  // @p{i}. there may be several such @p{i}s and their
-                  // weights' sum should be one. Then, @p{v[i]} should be
-                  // equal to @p{\sum_j w_{ij} p[j]} with @p{p[j]} be the
-                  // values of the degrees of freedom on the coarse grid.
-                  // we can thus compute constraints which link the degrees
-                  // of freedom @p{v[i]} on the fine grid to those on the
-                  // coarse grid, @p{p[j]}. Now to use these as real
-                  // constraints, rather than as additional equations, we
-                  // have to identify representants among the @p{i} for
-                  // each @p{j}. this will be done by simply taking the
-                  // first @p{i} for which @p{w_{ij}==1}.
-                  //
-                  // guard modification of the weights array by a Mutex.
-                  // since it should happen rather rarely that there are
-                  // several threads operating on different intergrid
-                  // weights, have only one mutex for all of them
-                  static Threads::Mutex mutex;
-                  Threads::Mutex::ScopedLock lock (mutex);
-                  for (types::global_dof_index i=0; i<global_parameter_representation.size(); ++i)
-                    // set this weight if it belongs to a parameter dof.
-                    if (weight_mapping[i] != numbers::invalid_dof_index)
-                      {
-                        // only overwrite old value if not by zero
-                        if (global_parameter_representation(i) != 0)
-                          {
-                            const types::global_dof_index wi = parameter_dof_indices[local_dof],
-                                                          wj = weight_mapping[i];
-                            weights[wi][wj] = global_parameter_representation(i);
-                          };
-                      }
-                    else
-                      Assert (global_parameter_representation(i) == 0,
-                              ExcInternalError());
-                }
-          }
-      }
-
-
-      /**
-       * This is a helper function that is used in the computation of
-       * integrid constraints. See the function for a thorough description
-       * of how it works.
-       */
-      template <int dim, int spacedim>
-      void
-      compute_intergrid_weights_2 (
-        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
-        const unsigned int                  coarse_component,
-        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
-        const std::vector<dealii::Vector<double> > &parameter_dofs,
-        const std::vector<types::global_dof_index>             &weight_mapping,
-        std::vector<std::map<types::global_dof_index,float> > &weights)
-      {
-        // simply distribute the range of cells to different threads
-        typedef typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
-        std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
-        cell_intervals = Threads::split_range<active_cell_iterator> (coarse_grid.begin_active(),
-                         coarse_grid.end(),
-                         multithread_info.n_default_threads);
-
-        // TODO: use WorkStream here
-
-        Threads::TaskGroup<> tasks;
-        void (*fun_ptr) (const dealii::DoFHandler<dim,spacedim> &,
-                         const unsigned int                  ,
-                         const InterGridMap<dealii::DoFHandler<dim,spacedim> > &,
-                         const std::vector<dealii::Vector<double> > &,
-                         const std::vector<types::global_dof_index> &,
-                         std::vector<std::map<types::global_dof_index, float> > &,
-                         const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &,
-                         const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &)
-          = &compute_intergrid_weights_3<dim>;
-        for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
-          tasks += Threads::new_task (fun_ptr,
-                                      coarse_grid, coarse_component,
-                                      coarse_to_fine_grid_map, parameter_dofs,
-                                      weight_mapping, weights,
-                                      cell_intervals[i].first,
-                                      cell_intervals[i].second);
-
-        // wait for the tasks to finish
-        tasks.join_all ();
-      }
-
-
-
-      /**
-       * This is a helper function that is used in the computation of
-       * integrid constraints. See the function for a thorough description
-       * of how it works.
-       */
-      template <int dim, int spacedim>
-      unsigned int
-      compute_intergrid_weights_1 (
-        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
-        const unsigned int                  coarse_component,
-        const dealii::DoFHandler<dim,spacedim>              &fine_grid,
-        const unsigned int                  fine_component,
-        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
-        std::vector<std::map<types::global_dof_index, float> > &weights,
-        std::vector<types::global_dof_index>                   &weight_mapping)
-      {
-        // aliases to the finite elements used by the dof handlers:
-        const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe(),
-                                           &fine_fe   = fine_grid.get_fe();
-
-        // global numbers of dofs
-        const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs(),
-                                      n_fine_dofs   = fine_grid.n_dofs();
-
-        // local numbers of dofs
-        const unsigned int fine_dofs_per_cell   = fine_fe.dofs_per_cell;
-
-        // alias the number of dofs per cell belonging to the
-        // coarse_component which is to be the restriction of the fine
-        // grid:
-        const unsigned int coarse_dofs_per_cell_component
-          = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell;
-
-
-        // Try to find out whether the grids stem from the same coarse
-        // grid. This is a rather crude test, but better than nothing
-        Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0),
-                ExcGridsDontMatch());
-
-        // check whether the map correlates the right objects
-        Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
-                ExcGridsDontMatch ());
-        Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
-                ExcGridsDontMatch ());
-
-
-        // check whether component numbers are valid
-        AssertIndexRange (coarse_component,coarse_fe.n_components());
-        AssertIndexRange (fine_component, fine_fe.n_components());
-
-        // check whether respective finite elements are equal
-        Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first)
-                ==
-                fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
-                ExcFiniteElementsDontMatch());
-
-#ifdef DEBUG
-        // if in debug mode, check whether the coarse grid is indeed
-        // coarser everywhere than the fine grid
-        for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
-             cell=coarse_grid.begin_active();
-             cell != coarse_grid.end(); ++cell)
-          Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
-                  ExcGridNotCoarser());
-#endif
-
-        /*
-         * From here on: the term `parameter' refers to the selected
-         * component on the coarse grid and its analogon on the fine grid.
-         * The naming of variables containing this term is due to the fact
-         * that `selected_component' is longer, but also due to the fact
-         * that the code of this function was initially written for a
-         * program where the component which we wanted to match between
-         * grids was actually the `parameter' variable.
-         *
-         * Likewise, the terms `parameter grid' and `state grid' refer to
-         * the coarse and fine grids, respectively.
-         *
-         * Changing the names of variables would in principle be a good
-         * idea, but would not make things simpler and would be another
-         * source of errors. If anyone feels like doing so: patches would
-         * be welcome!
-         */
-
-
-
-        // set up vectors of cell-local data; each vector represents one
-        // degree of freedom of the coarse-grid variable in the fine-grid
-        // element
-        std::vector<dealii::Vector<double> >
-        parameter_dofs (coarse_dofs_per_cell_component,
-                        dealii::Vector<double>(fine_dofs_per_cell));
-        // for each coarse dof: find its position within the fine element
-        // and set this value to one in the respective vector (all other
-        // values are zero by construction)
-        for (unsigned int local_coarse_dof=0;
-             local_coarse_dof<coarse_dofs_per_cell_component;
-             ++local_coarse_dof)
-          for (unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
-            if (fine_fe.system_to_component_index(fine_dof)
-                ==
-                std::make_pair (fine_component, local_coarse_dof))
-              {
-                parameter_dofs[local_coarse_dof](fine_dof) = 1.;
-                break;
-              };
-
-
-        // find out how many DoFs there are on the grids belonging to the
-        // components we want to match
-        unsigned int n_parameters_on_fine_grid=0;
-        if (true)
-          {
-            // have a flag for each dof on the fine grid and set it to true
-            // if this is an interesting dof. finally count how many true's
-            // there
-            std::vector<bool> dof_is_interesting (fine_grid.n_dofs(), false);
-            std::vector<types::global_dof_index>  local_dof_indices (fine_fe.dofs_per_cell);
-
-            for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
-                 cell=fine_grid.begin_active();
-                 cell!=fine_grid.end(); ++cell)
-              {
-                cell->get_dof_indices (local_dof_indices);
-                for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
-                  if (fine_fe.system_to_component_index(i).first == fine_component)
-                    dof_is_interesting[local_dof_indices[i]] = true;
-              };
-
-            n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
-                                                    dof_is_interesting.end(),
-                                                    true);
-          };
-
-
-        // set up the weights mapping
-        weights.clear ();
-        weights.resize (n_coarse_dofs);
-
-        weight_mapping.clear ();
-        weight_mapping.resize (n_fine_dofs, numbers::invalid_dof_index);
-
-        if (true)
-          {
-            std::vector<types::global_dof_index> local_dof_indices(fine_fe.dofs_per_cell);
-            unsigned int next_free_index=0;
-            for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
-                 cell=fine_grid.begin_active();
-                 cell != fine_grid.end(); ++cell)
-              {
-                cell->get_dof_indices (local_dof_indices);
-                for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
-                  // if this DoF is a parameter dof and has not yet been
-                  // numbered, then do so
-                  if ((fine_fe.system_to_component_index(i).first == fine_component) &&
-                      (weight_mapping[local_dof_indices[i]] == numbers::invalid_dof_index))
-                    {
-                      weight_mapping[local_dof_indices[i]] = next_free_index;
-                      ++next_free_index;
-                    };
-              };
-
-            Assert (next_free_index == n_parameters_on_fine_grid,
-                    ExcInternalError());
-          };
-
-
-        // for each cell on the parameter grid: find out which degrees of
-        // freedom on the fine grid correspond in which way to the degrees
-        // of freedom on the parameter grid
-        //
-        // do this in a separate function to allow for multithreading
-        // there. see this function also if you want to read more
-        // information on the algorithm used.
-        compute_intergrid_weights_2 (coarse_grid, coarse_component,
-                                     coarse_to_fine_grid_map, parameter_dofs,
-                                     weight_mapping, weights);
-
-
-        // ok, now we have all weights for each dof on the fine grid. if in
-        // debug mode lets see if everything went smooth, i.e. each dof has
-        // sum of weights one
-        //
-        // in other words this means that if the sum of all shape functions
-        // on the parameter grid is one (which is always the case), then
-        // the representation on the state grid should be as well (division
-        // of unity)
-        //
-        // if the parameter grid has more than one component, then the
-        // respective dofs of the other components have sum of weights
-        // zero, of course. we do not explicitly ask which component a dof
-        // belongs to, but this at least tests some errors
-#ifdef DEBUG
-        for (unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
-          {
-            double sum=0;
-            for (types::global_dof_index row=0; row<n_coarse_dofs; ++row)
-              if (weights[row].find(col) != weights[row].end())
-                sum += weights[row][col];
-            Assert ((std::fabs(sum-1) < 1.e-12) ||
-                    ((coarse_fe.n_components()>1) && (sum==0)), ExcInternalError());
-          };
-#endif
-
-
-        return n_parameters_on_fine_grid;
-      }
-
-
-    }
-  }
-
-
-
-  template <int dim, int spacedim>
-  void
-  compute_intergrid_constraints (
-    const DoFHandler<dim,spacedim>              &coarse_grid,
-    const unsigned int                  coarse_component,
-    const DoFHandler<dim,spacedim>              &fine_grid,
-    const unsigned int                  fine_component,
-    const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
-    ConstraintMatrix                   &constraints)
-  {
-    // store the weights with which a dof on the parameter grid contributes
-    // to a dof on the fine grid. see the long doc below for more info
-    //
-    // allocate as many rows as there are parameter dofs on the coarse grid
-    // and as many columns as there are parameter dofs on the fine grid.
-    //
-    // weight_mapping is used to map the global (fine grid) parameter dof
-    // indices to the columns
-    //
-    // in the original implementation, the weights array was actually of
-    // FullMatrix<double> type. this wasted huge amounts of memory, but was
-    // fast. nonetheless, since the memory consumption was quadratic in the
-    // number of degrees of freedom, this was not very practical, so we now
-    // use a vector of rows of the matrix, and in each row a vector of
-    // pairs (colnum,value). this seems like the best tradeoff between
-    // memory and speed, as it is now linear in memory and still fast
-    // enough.
-    //
-    // to save some memory and since the weights are usually (negative)
-    // powers of 2, we choose the value type of the matrix to be @p{float}
-    // rather than @p{double}.
-    std::vector<std::map<types::global_dof_index, float> > weights;
-
-    // this is this mapping. there is one entry for each dof on the fine
-    // grid; if it is a parameter dof, then its value is the column in
-    // weights for that parameter dof, if it is any other dof, then its
-    // value is -1, indicating an error
-    std::vector<types::global_dof_index> weight_mapping;
-
-    const unsigned int n_parameters_on_fine_grid
-      = internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
-                                               fine_grid, fine_component,
-                                               coarse_to_fine_grid_map,
-                                               weights, weight_mapping);
-
-    // global numbers of dofs
-    const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs(),
-                                  n_fine_dofs   = fine_grid.n_dofs();
-
-
-    // get an array in which we store which dof on the coarse grid is a
-    // parameter and which is not
-    std::vector<bool> coarse_dof_is_parameter (coarse_grid.n_dofs());
-    if (true)
-      {
-        std::vector<bool> mask (coarse_grid.get_fe().n_components(),
-                                false);
-        mask[coarse_component] = true;
-        extract_dofs (coarse_grid, ComponentMask(mask), coarse_dof_is_parameter);
-      }
-
-    // now we know that the weights in each row constitute a constraint.
-    // enter this into the constraints object
-    //
-    // first task: for each parameter dof on the parameter grid, find a
-    // representant on the fine, global grid. this is possible since we use
-    // conforming finite element. we take this representant to be the first
-    // element in this row with weight identical to one. the representant
-    // will become an unconstrained degree of freedom, while all others
-    // will be constrained to this dof (and possibly others)
-    std::vector<types::global_dof_index> representants(n_coarse_dofs, numbers::invalid_dof_index);
-    for (types::global_dof_index parameter_dof=0; parameter_dof<n_coarse_dofs;
-         ++parameter_dof)
-      if (coarse_dof_is_parameter[parameter_dof] == true)
-        {
-          // if this is the line of a parameter dof on the coarse grid,
-          // then it should have at least one dependent node on the fine
-          // grid
-          Assert (weights[parameter_dof].size() > 0, ExcInternalError());
-
-          // find the column where the representant is mentioned
-          std::map<types::global_dof_index,float>::const_iterator i = weights[parameter_dof].begin();
-          for (; i!=weights[parameter_dof].end(); ++i)
-            if (i->second == 1)
-              break;
-          Assert (i!=weights[parameter_dof].end(), ExcInternalError());
-          const types::global_dof_index column = i->first;
-
-          // now we know in which column of weights the representant is,
-          // but we don't know its global index. get it using the inverse
-          // operation of the weight_mapping
-          types::global_dof_index global_dof=0;
-          for (; global_dof<weight_mapping.size(); ++global_dof)
-            if (weight_mapping[global_dof] == static_cast<types::global_dof_index>(column))
-              break;
-          Assert (global_dof < weight_mapping.size(), ExcInternalError());
-
-          // now enter the representants global index into our list
-          representants[parameter_dof] = global_dof;
-        }
-      else
-        {
-          // consistency check: if this is no parameter dof on the coarse
-          // grid, then the respective row must be empty!
-          Assert (weights[parameter_dof].size() == 0, ExcInternalError());
-        };
-
-
-
-    // note for people that want to optimize this function: the largest
-    // part of the computing time is spent in the following, rather
-    // innocent block of code. basically, it must be the
-    // ConstraintMatrix::add_entry call which takes the bulk of the time,
-    // but it is not known to the author how to make it faster...
-    std::vector<std::pair<types::global_dof_index,double> > constraint_line;
-    for (types::global_dof_index global_dof=0; global_dof<n_fine_dofs; ++global_dof)
-      if (weight_mapping[global_dof] != numbers::invalid_dof_index)
-        // this global dof is a parameter dof, so it may carry a constraint
-        // note that for each global dof, the sum of weights shall be one,
-        // so we can find out whether this dof is constrained in the
-        // following way: if the only weight in this row is a one, and the
-        // representant for the parameter dof of the line in which this one
-        // is is the present dof, then we consider this dof to be
-        // unconstrained. otherwise, all other dofs are constrained
-        {
-          const types::global_dof_index col = weight_mapping[global_dof];
-          Assert (col < n_parameters_on_fine_grid, ExcInternalError());
-
-          types::global_dof_index first_used_row=0;
-
-          {
-            Assert (weights.size() > 0, ExcInternalError());
-            std::map<types::global_dof_index,float>::const_iterator
-            col_entry = weights[0].end();
-            for (; first_used_row<n_coarse_dofs; ++first_used_row)
-              {
-                col_entry = weights[first_used_row].find(col);
-                if (col_entry != weights[first_used_row].end())
-                  break;
-              }
-
-            Assert (col_entry != weights[first_used_row].end(), ExcInternalError());
-
-            if ((col_entry->second == 1) &&
-                (representants[first_used_row] == global_dof))
-              // dof unconstrained or constrained to itself (in case this
-              // cell is mapped to itself, rather than to children of
-              // itself)
-              continue;
-          }
-
-
-          // otherwise enter all constraints
-          constraints.add_line (global_dof);
-
-          constraint_line.clear ();
-          for (types::global_dof_index row=first_used_row; row<n_coarse_dofs; ++row)
-            {
-              const std::map<types::global_dof_index,float>::const_iterator
-              j = weights[row].find(col);
-              if ((j != weights[row].end()) && (j->second != 0))
-                constraint_line.push_back (std::pair<types::global_dof_index,double>(representants[row],
-                                           j->second));
-            };
-
-          constraints.add_entries (global_dof, constraint_line);
-        };
-  }
-
-
-
-  template <int dim, int spacedim>
-  void
-  compute_intergrid_transfer_representation (
-    const DoFHandler<dim,spacedim>              &coarse_grid,
-    const unsigned int                  coarse_component,
-    const DoFHandler<dim,spacedim>              &fine_grid,
-    const unsigned int                  fine_component,
-    const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
-    std::vector<std::map<types::global_dof_index, float> > &transfer_representation)
-  {
-    // store the weights with which a dof on the parameter grid contributes
-    // to a dof on the fine grid. see the long doc below for more info
-    //
-    // allocate as many rows as there are parameter dofs on the coarse grid
-    // and as many columns as there are parameter dofs on the fine grid.
-    //
-    // weight_mapping is used to map the global (fine grid) parameter dof
-    // indices to the columns
-    //
-    // in the original implementation, the weights array was actually of
-    // FullMatrix<double> type. this wasted huge amounts of memory, but was
-    // fast. nonetheless, since the memory consumption was quadratic in the
-    // number of degrees of freedom, this was not very practical, so we now
-    // use a vector of rows of the matrix, and in each row a vector of
-    // pairs (colnum,value). this seems like the best tradeoff between
-    // memory and speed, as it is now linear in memory and still fast
-    // enough.
-    //
-    // to save some memory and since the weights are usually (negative)
-    // powers of 2, we choose the value type of the matrix to be @p{float}
-    // rather than @p{double}.
-    std::vector<std::map<types::global_dof_index, float> > weights;
-
-    // this is this mapping. there is one entry for each dof on the fine
-    // grid; if it is a parameter dof, then its value is the column in
-    // weights for that parameter dof, if it is any other dof, then its
-    // value is -1, indicating an error
-    std::vector<types::global_dof_index> weight_mapping;
-
-    internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
-                                           fine_grid, fine_component,
-                                           coarse_to_fine_grid_map,
-                                           weights, weight_mapping);
-
-    // now compute the requested representation
-    const types::global_dof_index n_global_parm_dofs
-      = std::count_if (weight_mapping.begin(), weight_mapping.end(),
-                       std::bind2nd (std::not_equal_to<types::global_dof_index> (), numbers::invalid_dof_index));
-
-    // first construct the inverse mapping of weight_mapping
-    std::vector<types::global_dof_index> inverse_weight_mapping (n_global_parm_dofs,
-        DoFHandler<dim,spacedim>::invalid_dof_index);
-    for (types::global_dof_index i=0; i<weight_mapping.size(); ++i)
-      {
-        const types::global_dof_index parameter_dof = weight_mapping[i];
-        // if this global dof is a parameter
-        if (parameter_dof != numbers::invalid_dof_index)
-          {
-            Assert (parameter_dof < n_global_parm_dofs, ExcInternalError());
-            Assert ((inverse_weight_mapping[parameter_dof] == DoFHandler<dim,spacedim>::invalid_dof_index),
-                    ExcInternalError());
-
-            inverse_weight_mapping[parameter_dof] = i;
-          };
-      };
-
-    // next copy over weights array and replace respective numbers
-    const types::global_dof_index n_rows = weight_mapping.size();
-
-    transfer_representation.clear ();
-    transfer_representation.resize (n_rows);
-
-    const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs();
-    for (types::global_dof_index i=0; i<n_coarse_dofs; ++i)
-      {
-        std::map<types::global_dof_index, float>::const_iterator j = weights[i].begin();
-        for (; j!=weights[i].end(); ++j)
-          {
-            const types::global_dof_index p = inverse_weight_mapping[j->first];
-            Assert (p<n_rows, ExcInternalError());
-
-            transfer_representation[p][i] = j->second;
-          };
-      };
-  }
-
-
-
   template <class DH>
   void
   map_dof_to_boundary_indices (const DH                  &dof_handler,
@@ -5689,87 +1811,6 @@ namespace DoFTools
 
 
 
-  template <int dim, int spacedim, template <int,int> class DH>
-  void
-  make_zero_boundary_constraints (const DH<dim, spacedim> &dof,
-                                  const types::boundary_id boundary_indicator,
-                                  ConstraintMatrix        &zero_boundary_constraints,
-                                  const ComponentMask     &component_mask)
-  {
-    Assert (component_mask.represents_n_components(dof.get_fe().n_components()),
-            ExcMessage ("The number of components in the mask has to be either "
-                        "zero or equal to the number of components in the finite "
-                        "element."));
-
-    const unsigned int n_components = DoFTools::n_components (dof);
-
-    Assert (component_mask.n_selected_components(n_components) > 0,
-            VectorTools::ExcNoComponentSelected());
-
-    // a field to store the indices
-    std::vector<types::global_dof_index> face_dofs;
-    face_dofs.reserve (max_dofs_per_face(dof));
-
-    typename DH<dim,spacedim>::active_cell_iterator
-    cell = dof.begin_active(),
-    endc = dof.end();
-    for (; cell!=endc; ++cell)
-      if (!cell->is_artificial())
-        for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
-             ++face_no)
-          {
-            const FiniteElement<dim,spacedim> &fe = cell->get_fe();
-
-            const typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
-
-            // if face is on the boundary and satisfies the correct
-            // boundary id property
-            if (face->at_boundary ()
-                &&
-                ((boundary_indicator == numbers::invalid_boundary_id)
-                 ||
-                 (face->boundary_indicator() == boundary_indicator)))
-              {
-                // get indices and physical location on this face
-                face_dofs.resize (fe.dofs_per_face);
-                face->get_dof_indices (face_dofs, cell->active_fe_index());
-
-                // enter those dofs into the list that match the component
-                // signature.
-                for (unsigned int i=0; i<face_dofs.size(); ++i)
-                  {
-                    // Find out if a dof has a contribution in this
-                    // component, and if so, add it to the list
-                    const ComponentMask &nonzero_component_array
-                      = cell->get_fe().get_nonzero_components (i);
-                    bool nonzero = false;
-                    for (unsigned int c=0; c<n_components; ++c)
-                      if (nonzero_component_array[c] && component_mask[c])
-                        {
-                          nonzero = true;
-                          break;
-                        }
-
-                    if (nonzero)
-                      zero_boundary_constraints.add_line (face_dofs[i]);
-                  }
-              }
-          }
-  }
-
-
-
-  template <int dim, int spacedim, template <int,int> class DH>
-  void
-  make_zero_boundary_constraints (const DH<dim, spacedim> &dof,
-                                  ConstraintMatrix        &zero_boundary_constraints,
-                                  const ComponentMask     &component_mask)
-  {
-    make_zero_boundary_constraints(dof, numbers::invalid_boundary_id,
-                                   zero_boundary_constraints, component_mask);
-  }
-
-
   template <class DH, class Sparsity>
   void make_cell_patches(
     Sparsity &block_list,
@@ -6029,7 +2070,9 @@ namespace DoFTools
           }
       }
   }
-}
+
+
+} // end of namespace DoFTools
 
 
 
index 17d1beaa6caae0580143f1fd7da74d51ae016837..f4121a9d63dc3533974f6883880f0b7bcfde8115 100644 (file)
 // ---------------------------------------------------------------------
 
 
-
 for (SP : SPARSITY_PATTERNS; deal_II_dimension : DIMENSIONS)
   {
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<MGDoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const MGDoFHandler<deal_II_dimension,deal_II_dimension> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<MGDoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const MGDoFHandler<deal_II_dimension,deal_II_dimension>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension> &dof_row,
-     const DoFHandler<deal_II_dimension,deal_II_dimension> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof_row,
-     const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
-    (const DoFHandler<deal_II_dimension>& dof,
-     const std::vector<types::global_dof_index>  &,
-     SP    &);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
-    (const hp::DoFHandler<deal_II_dimension>& dof,
-     const std::vector<types::global_dof_index>  &,
-     SP    &);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
-    (const DoFHandler<deal_II_dimension>& dof,
-     const FunctionMap<deal_II_dimension>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
-    (const hp::DoFHandler<deal_II_dimension>& dof,
-     const FunctionMap<deal_II_dimension>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
-
-#if deal_II_dimension < 3
-    template void
-    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
-     const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
- #endif
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
-    (const DoFHandler<deal_II_dimension> &dof,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
-    (const hp::DoFHandler<deal_II_dimension> &dof,
-     SP    &sparsity);
-
-    template void
-      DoFTools::make_cell_patches<DoFHandler<deal_II_dimension>,SP>
-      (SP&, const DoFHandler<deal_II_dimension>&, const unsigned int, const std::vector<bool>&, types::global_dof_index);
-
-    template void
-      DoFTools::make_cell_patches<MGDoFHandler<deal_II_dimension>,SP>
-      (SP&, const MGDoFHandler<deal_II_dimension>&, const unsigned int, const std::vector<bool>&, types::global_dof_index);
-
-#if deal_II_dimension > 1
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
-    (const DoFHandler<deal_II_dimension> &dof,
-     SP    &,
-     const Table<2,Coupling>&,
-     const Table<2,Coupling>&);
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
-    (const DoFHandler<deal_II_dimension> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &constraints,
-     const bool, const unsigned int);
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
-    (const hp::DoFHandler<deal_II_dimension> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &constraints,
-     const bool, const unsigned int);
-
-    template void
-    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
-    (const hp::DoFHandler<deal_II_dimension> &dof,
-     SP    &,
-     const Table<2,Coupling>&,
-     const Table<2,Coupling>&);
-#endif
-
-#if deal_II_dimension < 3
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
-     const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
-    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
-     const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
-     const std::vector<types::global_dof_index>  &,
-     SP    &);
-
-    //template void
-    //DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
-    //(const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
-    // const std::vector<types::global_dof_index>  &,
-    // SP    &);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
-    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
-     const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
-
-    //template void
-    //DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
-    //(const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
-    // const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
-    // const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-    // SP    &sparsity);
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
-    (const DoFHandler<1,3> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
-    (const hp::DoFHandler<1,3> &dof,
-     SP    &sparsity,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
-    (const DoFHandler<1,3>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
-    (const hp::DoFHandler<1,3>&,
-     const Table<2,Coupling>&,
-     SP &,
-     const ConstraintMatrix &,
-     const bool,
-     const unsigned int);
-
-    template void
-    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
-    (const DoFHandler<1,3> &dof_row,
-     const DoFHandler<1,3> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
-    (const hp::DoFHandler<1,3> &dof_row,
-     const hp::DoFHandler<1,3> &dof_col,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<1,3>,SP>
-    (const DoFHandler<1,3>& dof,
-     const std::vector<types::global_dof_index>  &,
-     SP    &);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<1,3>,SP>
-    (const hp::DoFHandler<1,3>& dof,
-     const std::vector<types::global_dof_index>  &,
-     SP    &);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<DoFHandler<1,3>,SP>
-    (const DoFHandler<1,3>& dof,
-     const FunctionMap<3>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
-
-    template void
-    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<1,3>,SP>
-    (const hp::DoFHandler<1,3>& dof,
-     const FunctionMap<3>::type  &boundary_indicators,
-     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
-     SP    &sparsity);
-
-#endif
-
-  }
-
+   template void
+   DoFTools::make_cell_patches<DoFHandler<deal_II_dimension>,SP>
+   (SP&, const DoFHandler<deal_II_dimension>&, const unsigned int, const std::vector<bool>&, types::global_dof_index);
 
-
-
-for (DH : DOFHANDLERS; deal_II_dimension : DIMENSIONS)
-{
-  template
-  void
-  DoFTools::make_hanging_node_constraints (const DH &dof_handler,
-                                           ConstraintMatrix &constraints);
-}
-
-
-
-for (DH : DOFHANDLERS; deal_II_dimension : DIMENSIONS)
-{
-
-#if deal_II_dimension != 1
-  template
-  void
-  DoFTools::make_periodicity_constraints (const DH::face_iterator &,
-                                          const DH::face_iterator &,
-                                          dealii::ConstraintMatrix &,
-                                          const ComponentMask &,
-                                          bool, bool, bool);
-
-  template
-  void
-  DoFTools::make_periodicity_constraints(const DH &,
-                                         const types::boundary_id,
-                                         const types::boundary_id,
-                                         const int,
-                                         dealii::ConstraintMatrix &,
-                                         const ComponentMask &);
-
-  template
-  void
-  DoFTools::make_periodicity_constraints(const DH &,
-                                         const types::boundary_id,
-                                         const types::boundary_id,
-                                         const int,
-                                         dealii::Tensor<1,DH::space_dimension> &,
-                                         dealii::ConstraintMatrix &,
-                                         const ComponentMask &);
-
-  template
-  void
-  DoFTools::make_periodicity_constraints(const DH &,
-                                         const types::boundary_id,
-                                         const int,
-                                         dealii::ConstraintMatrix &,
-                                         const ComponentMask &);
-
-  template
-  void
-  DoFTools::make_periodicity_constraints(const DH &,
-                                         const types::boundary_id,
-                                         const int,
-                                         dealii::Tensor<1,DH::space_dimension> &,
-                                         dealii::ConstraintMatrix &,
-                                         const ComponentMask &);
-#endif
+   template void
+   DoFTools::make_cell_patches<MGDoFHandler<deal_II_dimension>,SP>
+   (SP&, const MGDoFHandler<deal_II_dimension>&, const unsigned int, const std::vector<bool>&, types::global_dof_index);
 }
 
-for (deal_II_dimension : DIMENSIONS)
-{
-#if deal_II_dimension != 1
-  template
-  void
-  DoFTools::make_hanging_node_constraints (const MGDoFHandler<deal_II_dimension> &dof_handler,
-                                           ConstraintMatrix &constraints);
-
-#endif
- }
 
 
 for (deal_II_dimension : DIMENSIONS)
 {
-  template
-  Table<2,DoFTools::Coupling>
-  DoFTools::dof_couplings_from_component_couplings
-  (const FiniteElement<deal_II_dimension> &fe,
-   const Table<2,DoFTools::Coupling> &component_couplings);
-
   template
   void DoFTools::make_vertex_patches (SparsityPattern&, const DoFHandler<deal_II_dimension>&,
   unsigned int, bool, bool, bool, bool);
@@ -427,22 +54,6 @@ for (deal_II_dimension : DIMENSIONS)
   void DoFTools::make_child_patches(SparsityPattern&, const MGDoFHandler<deal_II_dimension>&,
   unsigned int, bool, bool);
 
-#if deal_II_dimension < 3
-template
-void
-DoFTools::
-make_hanging_node_constraints (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_handler,
-                               ConstraintMatrix &constraints);
-#endif
-
-#if deal_II_dimension == 3
-template
-void
-DoFTools::
-make_hanging_node_constraints (const DoFHandler<1,3> &dof_handler,
-                               ConstraintMatrix &constraints);
-#endif
-
 
 // TODO: can cleanup a bit more to fit into the scheme used above
 
@@ -912,23 +523,6 @@ DoFTools::count_dofs_per_component<deal_II_dimension> (
   const DoFHandler<deal_II_dimension>&,
   std::vector<types::global_dof_index>&, std::vector<unsigned int>);
 
-template
-void
-DoFTools::compute_intergrid_constraints<deal_II_dimension> (
-  const DoFHandler<deal_II_dimension> &, const unsigned int,
-  const DoFHandler<deal_II_dimension> &, const unsigned int,
-  const InterGridMap<DoFHandler<deal_II_dimension> > &,
-  ConstraintMatrix&);
-
-template
-void
-DoFTools::compute_intergrid_transfer_representation<deal_II_dimension>
-(const DoFHandler<deal_II_dimension> &, const unsigned int,
- const DoFHandler<deal_II_dimension> &, const unsigned int,
- const InterGridMap<DoFHandler<deal_II_dimension> > &,
- std::vector<std::map<types::global_dof_index, float> > &);
-
-
 template
 void
 DoFTools::map_dof_to_boundary_indices<DoFHandler<deal_II_dimension> >
@@ -1089,36 +683,6 @@ DoFTools::convert_couplings_to_blocks (
   const hp::DoFHandler<deal_II_dimension>&, const Table<2, Coupling>&,
   std::vector<Table<2,Coupling> >&);
 
-template
-void
-DoFTools::make_zero_boundary_constraints
-(const DoFHandler<deal_II_dimension> &,
- ConstraintMatrix                    &,
- const ComponentMask             &);
-
-template
-void
-DoFTools::make_zero_boundary_constraints
-(const DoFHandler<deal_II_dimension> &,
- const types::boundary_id          ,
- ConstraintMatrix                    &,
- const ComponentMask             &);
-
-template
-void
-DoFTools::make_zero_boundary_constraints
-(const hp::DoFHandler<deal_II_dimension> &,
- ConstraintMatrix                        &,
- const ComponentMask                 &);
-
-template
-void
-DoFTools::make_zero_boundary_constraints
-(const hp::DoFHandler<deal_II_dimension> &,
- const types::boundary_id          ,
- ConstraintMatrix                        &,
- const ComponentMask                 &);
-
 
 #if deal_II_dimension < 3
 
diff --git a/deal.II/source/dofs/dof_tools_constraints.cc b/deal.II/source/dofs/dof_tools_constraints.cc
new file mode 100644 (file)
index 0000000..6e21770
--- /dev/null
@@ -0,0 +1,2891 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1999 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/base/multithread_info.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/table.h>
+#include <deal.II/base/template_constraints.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/intergrid_map.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_tools.h>
+#include <deal.II/hp/fe_collection.h>
+#include <deal.II/hp/fe_values.h>
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/multigrid/mg_dof_handler.h>
+
+#include <algorithm>
+#include <numeric>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+
+namespace DoFTools
+{
+  namespace internal
+  {
+    namespace
+    {
+      inline bool
+      check_master_dof_list (const FullMatrix<double> &face_interpolation_matrix,
+                             const std::vector<types::global_dof_index> &master_dof_list)
+      {
+        const unsigned int N = master_dof_list.size();
+
+        FullMatrix<double> tmp (N,N);
+        for (unsigned int i=0; i<N; ++i)
+          for (unsigned int j=0; j<N; ++j)
+            tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
+
+        // then use the algorithm from FullMatrix::gauss_jordan on this
+        // matrix to find out whether it is singular. the algorithm there
+        // does piviting and at the end swaps rows back into their proper
+        // order -- we omit this step here, since we don't care about the
+        // inverse matrix, all we care about is whether the matrix is
+        // regular or singular
+
+        // first get an estimate of the size of the elements of this
+        // matrix, for later checks whether the pivot element is large
+        // enough, or whether we have to fear that the matrix is not
+        // regular
+        double diagonal_sum = 0;
+        for (unsigned int i=0; i<N; ++i)
+          diagonal_sum += std::fabs(tmp(i,i));
+        const double typical_diagonal_element = diagonal_sum/N;
+
+        // initialize the array that holds the permutations that we find
+        // during pivot search
+        std::vector<unsigned int> p(N);
+        for (unsigned int i=0; i<N; ++i)
+          p[i] = i;
+
+        for (unsigned int j=0; j<N; ++j)
+          {
+            // pivot search: search that part of the line on and right of
+            // the diagonal for the largest element
+            double       max = std::fabs(tmp(j,j));
+            unsigned int r   = j;
+            for (unsigned int i=j+1; i<N; ++i)
+              {
+                if (std::fabs(tmp(i,j)) > max)
+                  {
+                    max = std::fabs(tmp(i,j));
+                    r = i;
+                  }
+              }
+            // check whether the pivot is too small. if that is the case,
+            // then the matrix is singular and we shouldn't use this set of
+            // master dofs
+            if (max < 1.e-12*typical_diagonal_element)
+              return false;
+
+            // row interchange
+            if (r>j)
+              {
+                for (unsigned int k=0; k<N; ++k)
+                  std::swap (tmp(j,k), tmp(r,k));
+
+                std::swap (p[j], p[r]);
+              }
+
+            // transformation
+            const double hr = 1./tmp(j,j);
+            tmp(j,j) = hr;
+            for (unsigned int k=0; k<N; ++k)
+              {
+                if (k==j) continue;
+                for (unsigned int i=0; i<N; ++i)
+                  {
+                    if (i==j) continue;
+                    tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
+                  }
+              }
+            for (unsigned int i=0; i<N; ++i)
+              {
+                tmp(i,j) *= hr;
+                tmp(j,i) *= -hr;
+              }
+            tmp(j,j) = hr;
+          }
+
+        // everything went fine, so we can accept this set of master dofs
+        // (at least as far as they have already been collected)
+        return true;
+      }
+
+
+
+      /**
+       * When restricting, on a face, the degrees of freedom of fe1 to the
+       * space described by fe2 (for example for the complex case described
+       * in the @ref hp_paper "hp paper"), we have to select
+       * fe2.dofs_per_face out of the fe1.dofs_per_face face DoFs as the
+       * master DoFs, and the rest become slave dofs. This function selects
+       * which ones will be masters, and which ones will be slaves.
+       *
+       * The function assumes that master_dofs already has size
+       * fe1.dofs_per_face. After the function, exactly fe2.dofs_per_face
+       * entries will be true.
+       *
+       * The function is a bit complicated since it has to figure out a set
+       * a DoFs so that the corresponding rows in the face interpolation
+       * matrix are all linearly independent. we have a good heuristic (see
+       * the function body) for selecting these rows, but there are cases
+       * where this fails and we have to pick them differently. what we do
+       * is to run the heuristic and then go back to determine whether we
+       * have a set of rows with full row rank. if this isn't the case, go
+       * back and select dofs differently
+       */
+      template <int dim, int spacedim>
+      void
+      select_master_dofs_for_face_restriction (const FiniteElement<dim,spacedim> &fe1,
+                                               const FiniteElement<dim,spacedim> &fe2,
+                                               const FullMatrix<double> &face_interpolation_matrix,
+                                               std::vector<bool>        &master_dof_mask)
+      {
+        Assert (fe1.dofs_per_face >= fe2.dofs_per_face,
+                ExcInternalError());
+        AssertDimension (master_dof_mask.size(), fe1.dofs_per_face);
+
+        Assert (fe2.dofs_per_vertex <= fe1.dofs_per_vertex,
+                ExcInternalError());
+        Assert (fe2.dofs_per_line <= fe1.dofs_per_line,
+                ExcInternalError());
+        Assert ((dim < 3)
+                ||
+                (fe2.dofs_per_quad <= fe1.dofs_per_quad),
+                ExcInternalError());
+
+        // the idea here is to designate as many DoFs in fe1 per object
+        // (vertex, line, quad) as master as there are such dofs in fe2
+        // (indices are int, because we want to avoid the 'unsigned int < 0
+        // is always false warning for the cases at the bottom in 1d and
+        // 2d)
+        //
+        // as mentioned in the paper, it is not always easy to find a set
+        // of master dofs that produces an invertible matrix. to this end,
+        // we check in each step whether the matrix is still invertible and
+        // simply discard this dof if the matrix is not invertible anymore.
+        //
+        // the cases where we did have trouble in the past were with adding
+        // more quad dofs when Q3 and Q4 elements meet at a refined face in
+        // 3d (see the hp/crash_12 test that tests that we can do exactly
+        // this, and failed before we had code to compensate for this
+        // case). the other case are system elements: if we have say a Q1Q2
+        // vs a Q2Q3 element, then we can't just take all master dofs on a
+        // line from a single base element, since the shape functions of
+        // that base element are independent of that of the other one. this
+        // latter case shows up when running hp/hp_constraints_q_system_06
+
+        std::vector<types::global_dof_index> master_dof_list;
+        unsigned int index = 0;
+        for (int v=0;
+             v<static_cast<signed int>(GeometryInfo<dim>::vertices_per_face);
+             ++v)
+          {
+            unsigned int dofs_added = 0;
+            unsigned int i          = 0;
+            while (dofs_added < fe2.dofs_per_vertex)
+              {
+                // make sure that we were able to find a set of master dofs
+                // and that the code down below didn't just reject all our
+                // efforts
+                Assert (i < fe1.dofs_per_vertex,
+                        ExcInternalError());
+
+                // tentatively push this vertex dof
+                master_dof_list.push_back (index+i);
+
+                // then see what happens. if it succeeds, fine
+                if (check_master_dof_list (face_interpolation_matrix,
+                                           master_dof_list)
+                    == true)
+                  ++dofs_added;
+                else
+                  // well, it didn't. simply pop that dof from the list
+                  // again and try with the next dof
+                  master_dof_list.pop_back ();
+
+                // forward counter by one
+                ++i;
+              }
+            index += fe1.dofs_per_vertex;
+          }
+
+        for (int l=0;
+             l<static_cast<signed int>(GeometryInfo<dim>::lines_per_face);
+             ++l)
+          {
+            // same algorithm as above
+            unsigned int dofs_added = 0;
+            unsigned int i          = 0;
+            while (dofs_added < fe2.dofs_per_line)
+              {
+                Assert (i < fe1.dofs_per_line,
+                        ExcInternalError());
+
+                master_dof_list.push_back (index+i);
+                if (check_master_dof_list (face_interpolation_matrix,
+                                           master_dof_list)
+                    == true)
+                  ++dofs_added;
+                else
+                  master_dof_list.pop_back ();
+
+                ++i;
+              }
+            index += fe1.dofs_per_line;
+          }
+
+        for (int q=0;
+             q<static_cast<signed int>(GeometryInfo<dim>::quads_per_face);
+             ++q)
+          {
+            // same algorithm as above
+            unsigned int dofs_added = 0;
+            unsigned int i          = 0;
+            while (dofs_added < fe2.dofs_per_quad)
+              {
+                Assert (i < fe1.dofs_per_quad,
+                        ExcInternalError());
+
+                master_dof_list.push_back (index+i);
+                if (check_master_dof_list (face_interpolation_matrix,
+                                           master_dof_list)
+                    == true)
+                  ++dofs_added;
+                else
+                  master_dof_list.pop_back ();
+
+                ++i;
+              }
+            index += fe1.dofs_per_quad;
+          }
+
+        AssertDimension (index, fe1.dofs_per_face);
+        AssertDimension (master_dof_list.size(), fe2.dofs_per_face);
+
+        // finally copy the list into the mask
+        std::fill (master_dof_mask.begin(), master_dof_mask.end(), false);
+        for (std::vector<types::global_dof_index>::const_iterator i=master_dof_list.begin();
+             i!=master_dof_list.end(); ++i)
+          master_dof_mask[*i] = true;
+      }
+
+
+
+      /**
+       * Make sure that the mask exists that determines which dofs will be
+       * the masters on refined faces where an fe1 and a fe2 meet.
+       */
+      template <int dim, int spacedim>
+      void
+      ensure_existence_of_master_dof_mask (const FiniteElement<dim,spacedim> &fe1,
+                                           const FiniteElement<dim,spacedim> &fe2,
+                                           const FullMatrix<double> &face_interpolation_matrix,
+                                           std_cxx1x::shared_ptr<std::vector<bool> > &master_dof_mask)
+      {
+        if (master_dof_mask == std_cxx1x::shared_ptr<std::vector<bool> >())
+          {
+            master_dof_mask = std_cxx1x::shared_ptr<std::vector<bool> >
+                              (new std::vector<bool> (fe1.dofs_per_face));
+            select_master_dofs_for_face_restriction (fe1,
+                                                     fe2,
+                                                     face_interpolation_matrix,
+                                                     *master_dof_mask);
+          }
+      }
+
+
+
+      /**
+       * Make sure that the given @p face_interpolation_matrix pointer
+       * points to a valid matrix. If the pointer is zero beforehand,
+       * create an entry with the correct data. If it is nonzero, don't
+       * touch it.
+       */
+      template <int dim, int spacedim>
+      void
+      ensure_existence_of_face_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                       const FiniteElement<dim,spacedim> &fe2,
+                                       std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
+      {
+        if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
+          {
+            matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
+                     (new FullMatrix<double> (fe2.dofs_per_face,
+                                              fe1.dofs_per_face));
+            fe1.get_face_interpolation_matrix (fe2,
+                                               *matrix);
+          }
+      }
+
+
+
+      /**
+       * Same, but for subface interpolation matrices.
+       */
+      template <int dim, int spacedim>
+      void
+      ensure_existence_of_subface_matrix (const FiniteElement<dim,spacedim> &fe1,
+                                          const FiniteElement<dim,spacedim> &fe2,
+                                          const unsigned int        subface,
+                                          std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
+      {
+        if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
+          {
+            matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
+                     (new FullMatrix<double> (fe2.dofs_per_face,
+                                              fe1.dofs_per_face));
+            fe1.get_subface_interpolation_matrix (fe2,
+                                                  subface,
+                                                  *matrix);
+          }
+      }
+
+
+
+      /**
+       * Given the face interpolation matrix between two elements, split it
+       * into its master and slave parts and invert the master part as
+       * explained in the @ref hp_paper "hp paper".
+       */
+      void
+      ensure_existence_of_split_face_matrix (const FullMatrix<double> &face_interpolation_matrix,
+                                             const std::vector<bool> &master_dof_mask,
+                                             std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > &split_matrix)
+      {
+        AssertDimension (master_dof_mask.size(), face_interpolation_matrix.m());
+        Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(), true) ==
+                static_cast<signed int>(face_interpolation_matrix.n()),
+                ExcInternalError());
+
+        if (split_matrix ==
+            std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >())
+          {
+            split_matrix
+              = std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >
+                (new std::pair<FullMatrix<double>,FullMatrix<double> >());
+
+            const unsigned int n_master_dofs = face_interpolation_matrix.n();
+            const unsigned int n_dofs        = face_interpolation_matrix.m();
+
+            Assert (n_master_dofs <= n_dofs, ExcInternalError());
+
+            // copy and invert the master
+            // component, copy the slave
+            // component
+            split_matrix->first.reinit (n_master_dofs, n_master_dofs);
+            split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
+
+            unsigned int nth_master_dof = 0,
+                         nth_slave_dof  = 0;
+
+            for (unsigned int i=0; i<n_dofs; ++i)
+              if (master_dof_mask[i] == true)
+                {
+                  for (unsigned int j=0; j<n_master_dofs; ++j)
+                    split_matrix->first(nth_master_dof,j)
+                      = face_interpolation_matrix(i,j);
+                  ++nth_master_dof;
+                }
+              else
+                {
+                  for (unsigned int j=0; j<n_master_dofs; ++j)
+                    split_matrix->second(nth_slave_dof,j)
+                      = face_interpolation_matrix(i,j);
+                  ++nth_slave_dof;
+                }
+
+            AssertDimension (nth_master_dof, n_master_dofs);
+            AssertDimension (nth_slave_dof, n_dofs-n_master_dofs);
+
+            //TODO[WB]: We should make sure very small entries are removed after inversion
+            split_matrix->first.gauss_jordan ();
+          }
+      }
+
+
+      // a template that can determine statically whether a given
+      // DoFHandler class supports different finite element elements
+      template <typename>
+      struct DoFHandlerSupportsDifferentFEs
+      {
+        static const bool value = true;
+      };
+
+
+      template <int dim, int spacedim>
+      struct DoFHandlerSupportsDifferentFEs< dealii::DoFHandler<dim,spacedim> >
+      {
+        static const bool value = false;
+      };
+
+
+      /**
+       * A function that returns how many different finite elements a dof
+       * handler uses. This is one for non-hp DoFHandlers and
+       * dof_handler.get_fe().size() for the hp-versions.
+       */
+      template <int dim, int spacedim>
+      unsigned int
+      n_finite_elements (const dealii::hp::DoFHandler<dim,spacedim> &dof_handler)
+      {
+        return dof_handler.get_fe().size();
+      }
+
+
+      template <class DH>
+      unsigned int
+      n_finite_elements (const DH &)
+      {
+        return 1;
+      }
+
+
+      /**
+       * For a given face belonging to an active cell that borders to a
+       * more refined cell, return the fe_index of the most dominating
+       * finite element used on any of the face's subfaces.
+       */
+      template <typename face_iterator>
+      unsigned int
+      get_most_dominating_subface_fe_index (const face_iterator &face)
+      {
+        const unsigned int dim
+          = face_iterator::AccessorType::dimension;
+        const unsigned int spacedim
+          = face_iterator::AccessorType::space_dimension;
+
+        unsigned int dominating_subface_no = 0;
+        for (; dominating_subface_no<face->n_children();
+             ++dominating_subface_no)
+          {
+            // each of the subfaces can have only a single fe_index
+            // associated with them, since there is no cell on the other
+            // side
+            Assert (face->child(dominating_subface_no)
+                    ->n_active_fe_indices()
+                    == 1,
+                    ExcInternalError());
+
+            const FiniteElement<dim,spacedim> &
+            this_subface_fe = (face->child(dominating_subface_no)
+                               ->get_fe (face->child(dominating_subface_no)
+                                         ->nth_active_fe_index(0)));
+
+            FiniteElementDomination::Domination
+            domination = FiniteElementDomination::either_element_can_dominate;
+            for (unsigned int sf=0; sf<face->n_children(); ++sf)
+              if (sf != dominating_subface_no)
+                {
+                  const FiniteElement<dim,spacedim> &
+                  that_subface_fe = (face->child(sf)
+                                     ->get_fe (face->child(sf)
+                                               ->nth_active_fe_index(0)));
+
+                  domination = domination &
+                               this_subface_fe.compare_for_face_domination(that_subface_fe);
+                }
+
+            // see if the element on this subface is able to dominate the
+            // ones on all other subfaces, and if so take it
+            if ((domination == FiniteElementDomination::this_element_dominates)
+                ||
+                (domination == FiniteElementDomination::either_element_can_dominate))
+              break;
+          }
+
+        // check that we have found one such subface
+        Assert (dominating_subface_no < face->n_children(),
+                ExcNotImplemented());
+
+        // return the finite element index used on it. note that only a
+        // single fe can be active on such subfaces
+        return face->child (dominating_subface_no)->nth_active_fe_index(0);
+      }
+
+
+
+      /**
+       * Copy constraints into a constraint matrix object.
+       *
+       * This function removes zero constraints and those, which constrain
+       * a DoF which was already eliminated in one of the previous steps of
+       * the hp hanging node procedure.
+       *
+       * It also suppresses very small entries in the constraint matrix to
+       * avoid making the sparsity pattern fuller than necessary.
+       */
+      void
+      filter_constraints (const std::vector<types::global_dof_index> &master_dofs,
+                          const std::vector<types::global_dof_index> &slave_dofs,
+                          const FullMatrix<double> &face_constraints,
+                          ConstraintMatrix &constraints)
+      {
+        Assert (face_constraints.n () == master_dofs.size (),
+                ExcDimensionMismatch(master_dofs.size (),
+                                     face_constraints.n()));
+        Assert (face_constraints.m () == slave_dofs.size (),
+                ExcDimensionMismatch(slave_dofs.size (),
+                                     face_constraints.m()));
+
+        const unsigned int n_master_dofs = master_dofs.size ();
+        const unsigned int n_slave_dofs = slave_dofs.size ();
+
+        // check for a couple conditions that happened in parallel
+        // distributed mode
+        for (unsigned int row=0; row!=n_slave_dofs; ++row)
+          Assert (slave_dofs[row] != numbers::invalid_dof_index,
+                  ExcInternalError());
+        for (unsigned int col=0; col!=n_master_dofs; ++col)
+          Assert (master_dofs[col] != numbers::invalid_dof_index,
+                  ExcInternalError());
+
+
+        for (unsigned int row=0; row!=n_slave_dofs; ++row)
+          if (constraints.is_constrained (slave_dofs[row]) == false)
+            {
+              bool constraint_already_satisfied = false;
+
+              // Check if we have an identity constraint, which is already
+              // satisfied by unification of the corresponding global dof
+              // indices
+              for (unsigned int i=0; i<n_master_dofs; ++i)
+                if (face_constraints (row,i) == 1.0)
+                  if (master_dofs[i] == slave_dofs[row])
+                    {
+                      constraint_already_satisfied = true;
+                      break;
+                    }
+
+              if (constraint_already_satisfied == false)
+                {
+                  // add up the absolute values of all constraints in this
+                  // line to get a measure of their absolute size
+                  double abs_sum = 0;
+                  for (unsigned int i=0; i<n_master_dofs; ++i)
+                    abs_sum += std::abs (face_constraints(row,i));
+
+                  // then enter those constraints that are larger than
+                  // 1e-14*abs_sum. everything else probably originated
+                  // from inexact inversion of matrices and similar
+                  // effects. having those constraints in here will only
+                  // lead to problems because it makes sparsity patterns
+                  // fuller than necessary without producing any
+                  // significant effect
+                  constraints.add_line (slave_dofs[row]);
+                  for (unsigned int i=0; i<n_master_dofs; ++i)
+                    if ((face_constraints(row,i) != 0)
+                        &&
+                        (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
+                      constraints.add_entry (slave_dofs[row],
+                                             master_dofs[i],
+                                             face_constraints (row,i));
+                  constraints.set_inhomogeneity (slave_dofs[row], 0.);
+                }
+            }
+      }
+
+    }
+
+
+
+    void
+    make_hp_hanging_node_constraints (const dealii::DoFHandler<1> &,
+                                      ConstraintMatrix &)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+
+    void
+    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1> &,
+                                            ConstraintMatrix &,
+                                            dealii::internal::int2type<1>)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+    void
+    make_hp_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
+                                      ConstraintMatrix &)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+
+    void
+    make_oldstyle_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
+                                            ConstraintMatrix &,
+                                            dealii::internal::int2type<1>)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+    void
+    make_hp_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
+                                      ConstraintMatrix        &/*constraints*/)
+    {
+      // we may have to compute constraints for vertices. gotta think about
+      // that a bit more
+
+      //TODO[WB]: think about what to do here...
+    }
+
+
+
+    void
+    make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
+                                            ConstraintMatrix        &/*constraints*/,
+                                            dealii::internal::int2type<1>)
+    {
+      // we may have to compute constraints for vertices. gotta think about
+      // that a bit more
+
+      //TODO[WB]: think about what to do here...
+    }
+
+
+    void
+    make_hp_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
+                                      ConstraintMatrix &)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+
+    void
+    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
+                                            ConstraintMatrix &,
+                                            dealii::internal::int2type<1>)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+    void
+    make_hp_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
+                                      ConstraintMatrix &)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+    void
+    make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
+                                            ConstraintMatrix &,
+                                            dealii::internal::int2type<1>)
+    {
+      // nothing to do for regular dof handlers in 1d
+    }
+
+
+//   currently not used but may be in the future:
+
+//     void
+//     make_hp_hanging_node_constraints (const dealii::MDoFHandler<1,2> &,
+//                                    ConstraintMatrix    &)
+//     {
+//                                     // nothing to do for regular
+//                                     // dof handlers in 1d
+//     }
+
+
+
+//     void
+//     make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
+//                                          ConstraintMatrix    &,
+//                                          dealii::internal::int2type<1>)
+//     {
+//                                     // nothing to do for regular
+//                                     // dof handlers in 1d
+//     }
+
+
+//     void
+//     make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1,2> &/*dof_handler*/,
+//                                          ConstraintMatrix        &/*constraints*/,
+//                                          dealii::internal::int2type<1>)
+//     {
+//                                     // we may have to compute
+//                                     // constraints for
+//                                     // vertices. gotta think about
+//                                     // that a bit more
+//
+// //TODO[WB]: think about what to do here...
+//     }
+//#endif
+
+
+
+    template <class DH>
+    void
+    make_oldstyle_hanging_node_constraints (const DH         &dof_handler,
+                                            ConstraintMatrix &constraints,
+                                            dealii::internal::int2type<2>)
+    {
+      const unsigned int dim = 2;
+
+      const unsigned int spacedim = DH::space_dimension;
+
+      std::vector<types::global_dof_index> dofs_on_mother;
+      std::vector<types::global_dof_index> dofs_on_children;
+
+      // loop over all lines; only on lines there can be constraints. We do
+      // so by looping over all active cells and checking whether any of
+      // the faces are refined which can only be from the neighboring cell
+      // because this one is active. In that case, the face is subject to
+      // constraints
+      //
+      // note that even though we may visit a face twice if the neighboring
+      // cells are equally refined, we can only visit each face with
+      // hanging nodes once
+      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
+                                        endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+        // artificial cells can at best neighbor ghost cells, but we're not
+        // interested in these interfaces
+        if (!cell->is_artificial ())
+          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            if (cell->face(face)->has_children())
+              {
+                // in any case, faces can have at most two active fe
+                // indices, but here the face can have only one (namely the
+                // same as that from the cell we're sitting on), and each
+                // of the children can have only one as well. check this
+                Assert (cell->face(face)->n_active_fe_indices() == 1,
+                        ExcInternalError());
+                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+                        == true,
+                        ExcInternalError());
+                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+                    Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
+                            ExcInternalError());
+
+                // right now, all that is implemented is the case that both
+                // sides use the same fe
+                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+                    Assert (cell->face(face)->child(c)
+                            ->fe_index_is_active(cell->active_fe_index()) == true,
+                            ExcNotImplemented());
+
+                // ok, start up the work
+                const FiniteElement<dim,spacedim> &fe       = cell->get_fe();
+                const unsigned int        fe_index = cell->active_fe_index();
+
+                const unsigned int
+                n_dofs_on_mother   = 2*fe.dofs_per_vertex + fe.dofs_per_line,
+                n_dofs_on_children = fe.dofs_per_vertex + 2*fe.dofs_per_line;
+
+                dofs_on_mother.resize (n_dofs_on_mother);
+                dofs_on_children.resize (n_dofs_on_children);
+
+                Assert(n_dofs_on_mother == fe.constraints().n(),
+                       ExcDimensionMismatch(n_dofs_on_mother,
+                                            fe.constraints().n()));
+                Assert(n_dofs_on_children == fe.constraints().m(),
+                       ExcDimensionMismatch(n_dofs_on_children,
+                                            fe.constraints().m()));
+
+                const typename DH::line_iterator this_face = cell->face(face);
+
+                // fill the dofs indices. Use same enumeration scheme as in
+                // @p{FiniteElement::constraints()}
+                unsigned int next_index = 0;
+                for (unsigned int vertex=0; vertex<2; ++vertex)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                    dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
+                                                                               fe_index);
+                for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                  dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
+                AssertDimension (next_index, dofs_on_mother.size());
+
+                next_index = 0;
+                for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(0)->vertex_dof_index(1,dof,fe_index);
+                for (unsigned int child=0; child<2; ++child)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                    dofs_on_children[next_index++]
+                      = this_face->child(child)->dof_index(dof, fe_index);
+                AssertDimension (next_index, dofs_on_children.size());
+
+                // for each row in the constraint matrix for this line:
+                for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
+                  {
+                    constraints.add_line (dofs_on_children[row]);
+                    for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
+                      constraints.add_entry (dofs_on_children[row],
+                                             dofs_on_mother[i],
+                                             fe.constraints()(row,i));
+
+                    constraints.set_inhomogeneity (dofs_on_children[row], 0.);
+                  }
+              }
+            else
+              {
+                // this face has no children, but it could still be that it
+                // is shared by two cells that use a different fe index.
+                // check a couple of things, but ignore the case that the
+                // neighbor is an artificial cell
+                if (!cell->at_boundary(face) &&
+                    !cell->neighbor(face)->is_artificial())
+                  {
+                    Assert (cell->face(face)->n_active_fe_indices() == 1,
+                            ExcNotImplemented());
+                    Assert (cell->face(face)
+                            ->fe_index_is_active(cell->active_fe_index()) == true,
+                            ExcInternalError());
+                  }
+              }
+    }
+
+
+
+    template <class DH>
+    void
+    make_oldstyle_hanging_node_constraints (const DH         &dof_handler,
+                                            ConstraintMatrix &constraints,
+                                            dealii::internal::int2type<3>)
+    {
+      const unsigned int dim = 3;
+
+      std::vector<types::global_dof_index> dofs_on_mother;
+      std::vector<types::global_dof_index> dofs_on_children;
+
+      // loop over all quads; only on quads there can be constraints. We do
+      // so by looping over all active cells and checking whether any of
+      // the faces are refined which can only be from the neighboring cell
+      // because this one is active. In that case, the face is subject to
+      // constraints
+      //
+      // note that even though we may visit a face twice if the neighboring
+      // cells are equally refined, we can only visit each face with
+      // hanging nodes once
+      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
+                                        endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+        // artificial cells can at best neighbor ghost cells, but we're not
+        // interested in these interfaces
+        if (!cell->is_artificial ())
+          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            if (cell->face(face)->has_children())
+              {
+                // first of all, make sure that we treat a case which is
+                // possible, i.e. either no dofs on the face at all or no
+                // anisotropic refinement
+                if (cell->get_fe().dofs_per_face == 0)
+                  continue;
+
+                Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+                       ExcNotImplemented());
+
+                // in any case, faces can have at most two active fe
+                // indices, but here the face can have only one (namely the
+                // same as that from the cell we're sitting on), and each
+                // of the children can have only one as well. check this
+                AssertDimension (cell->face(face)->n_active_fe_indices(), 1);
+                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+                        == true,
+                        ExcInternalError());
+                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                  AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
+
+                // right now, all that is implemented is the case that both
+                // sides use the same fe, and not only that but also that
+                // all lines bounding this face and the children have the
+                // same fe
+                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                  if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+                    {
+                      Assert (cell->face(face)->child(c)
+                              ->fe_index_is_active(cell->active_fe_index()) == true,
+                              ExcNotImplemented());
+                      for (unsigned int e=0; e<4; ++e)
+                        {
+                          Assert (cell->face(face)->child(c)->line(e)
+                                  ->n_active_fe_indices() == 1,
+                                  ExcNotImplemented());
+                          Assert (cell->face(face)->child(c)->line(e)
+                                  ->fe_index_is_active(cell->active_fe_index()) == true,
+                                  ExcNotImplemented());
+                        }
+                    }
+                for (unsigned int e=0; e<4; ++e)
+                  {
+                    Assert (cell->face(face)->line(e)
+                            ->n_active_fe_indices() == 1,
+                            ExcNotImplemented());
+                    Assert (cell->face(face)->line(e)
+                            ->fe_index_is_active(cell->active_fe_index()) == true,
+                            ExcNotImplemented());
+                  }
+
+                // ok, start up the work
+                const FiniteElement<dim> &fe       = cell->get_fe();
+                const unsigned int        fe_index = cell->active_fe_index();
+
+                const unsigned int n_dofs_on_mother = fe.dofs_per_face;
+                const unsigned int n_dofs_on_children = (5*fe.dofs_per_vertex+
+                                                         12*fe.dofs_per_line+
+                                                         4*fe.dofs_per_quad);
+
+                //TODO[TL]: think about this and the following in case of anisotropic refinement
+
+                dofs_on_mother.resize (n_dofs_on_mother);
+                dofs_on_children.resize (n_dofs_on_children);
+
+                Assert(n_dofs_on_mother == fe.constraints().n(),
+                       ExcDimensionMismatch(n_dofs_on_mother,
+                                            fe.constraints().n()));
+                Assert(n_dofs_on_children == fe.constraints().m(),
+                       ExcDimensionMismatch(n_dofs_on_children,
+                                            fe.constraints().m()));
+
+                const typename DH::face_iterator this_face = cell->face(face);
+
+                // fill the dofs indices. Use same enumeration scheme as in
+                // @p{FiniteElement::constraints()}
+                unsigned int next_index = 0;
+                for (unsigned int vertex=0; vertex<4; ++vertex)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                    dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
+                                                                               fe_index);
+                for (unsigned int line=0; line<4; ++line)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                    dofs_on_mother[next_index++]
+                      = this_face->line(line)->dof_index(dof, fe_index);
+                for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+                  dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
+                AssertDimension (next_index, dofs_on_mother.size());
+
+                next_index = 0;
+
+                // assert some consistency assumptions
+
+                //TODO[TL]: think about this in case of anisotropic
+                //refinement
+
+                Assert (dof_handler.get_tria().get_anisotropic_refinement_flag() ||
+                        ((this_face->child(0)->vertex_index(3) ==
+                          this_face->child(1)->vertex_index(2)) &&
+                         (this_face->child(0)->vertex_index(3) ==
+                          this_face->child(2)->vertex_index(1)) &&
+                         (this_face->child(0)->vertex_index(3) ==
+                          this_face->child(3)->vertex_index(0))),
+                        ExcInternalError());
+                for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(0)->vertex_dof_index(3,dof);
+
+                // dof numbers on the centers of the lines bounding this
+                // face
+                for (unsigned int line=0; line<4; ++line)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+                    dofs_on_children[next_index++]
+                      = this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index);
+
+                // next the dofs on the lines interior to the face; the
+                // order of these lines is laid down in the FiniteElement
+                // class documentation
+                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(0)->line(1)->dof_index(dof, fe_index);
+                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(2)->line(1)->dof_index(dof, fe_index);
+                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(0)->line(3)->dof_index(dof, fe_index);
+                for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+                  dofs_on_children[next_index++]
+                    = this_face->child(1)->line(3)->dof_index(dof, fe_index);
+
+                // dofs on the bordering lines
+                for (unsigned int line=0; line<4; ++line)
+                  for (unsigned int child=0; child<2; ++child)
+                    for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+                      dofs_on_children[next_index++]
+                        = this_face->line(line)->child(child)->dof_index(dof, fe_index);
+
+                // finally, for the dofs interior to the four child faces
+                for (unsigned int child=0; child<4; ++child)
+                  for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+                    dofs_on_children[next_index++]
+                      = this_face->child(child)->dof_index(dof, fe_index);
+                AssertDimension (next_index, dofs_on_children.size());
+
+                // for each row in the constraint matrix for this line:
+                for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
+                  {
+                    constraints.add_line (dofs_on_children[row]);
+                    for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
+                      constraints.add_entry (dofs_on_children[row],
+                                             dofs_on_mother[i],
+                                             fe.constraints()(row,i));
+
+                    constraints.set_inhomogeneity(dofs_on_children[row], 0.);
+                  }
+              }
+            else
+              {
+                // this face has no children, but it could still be that it
+                // is shared by two cells that use a different fe index.
+                // check a couple of things, but ignore the case that the
+                // neighbor is an artificial cell
+                if (!cell->at_boundary(face) &&
+                    !cell->neighbor(face)->is_artificial())
+                  {
+                    Assert (cell->face(face)->n_active_fe_indices() == 1,
+                            ExcNotImplemented());
+                    Assert (cell->face(face)
+                            ->fe_index_is_active(cell->active_fe_index()) == true,
+                            ExcInternalError());
+                  }
+              }
+    }
+
+
+    template <class DH>
+    void
+    make_hp_hanging_node_constraints (const DH         &dof_handler,
+                                      ConstraintMatrix &constraints)
+    {
+      // note: this function is going to be hard to understand if you
+      // haven't read the hp paper. however, we try to follow the notation
+      // laid out there, so go read the paper before you try to understand
+      // what is going on here
+
+      const unsigned int dim = DH::dimension;
+
+      const unsigned int spacedim = DH::space_dimension;
+
+
+      // a matrix to be used for constraints below. declared here and
+      // simply resized down below to avoid permanent re-allocation of
+      // memory
+      FullMatrix<double> constraint_matrix;
+
+      // similarly have arrays that will hold master and slave dof numbers,
+      // as well as a scratch array needed for the complicated case below
+      std::vector<types::global_dof_index> master_dofs;
+      std::vector<types::global_dof_index> slave_dofs;
+      std::vector<types::global_dof_index> scratch_dofs;
+
+      // caches for the face and subface interpolation matrices between
+      // different (or the same) finite elements. we compute them only
+      // once, namely the first time they are needed, and then just reuse
+      // them
+      Table<2,std_cxx1x::shared_ptr<FullMatrix<double> > >
+      face_interpolation_matrices (n_finite_elements (dof_handler),
+                                   n_finite_elements (dof_handler));
+      Table<3,std_cxx1x::shared_ptr<FullMatrix<double> > >
+      subface_interpolation_matrices (n_finite_elements (dof_handler),
+                                      n_finite_elements (dof_handler),
+                                      GeometryInfo<dim>::max_children_per_face);
+
+      // similarly have a cache for the matrices that are split into their
+      // master and slave parts, and for which the master part is inverted.
+      // these two matrices are derived from the face interpolation matrix
+      // as described in the @ref hp_paper "hp paper"
+      Table<2,std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > >
+      split_face_interpolation_matrices (n_finite_elements (dof_handler),
+                                         n_finite_elements (dof_handler));
+
+      // finally, for each pair of finite elements, have a mask that states
+      // which of the degrees of freedom on the coarse side of a refined
+      // face will act as master dofs.
+      Table<2,std_cxx1x::shared_ptr<std::vector<bool> > >
+      master_dof_masks (n_finite_elements (dof_handler),
+                        n_finite_elements (dof_handler));
+
+      // loop over all faces
+      //
+      // note that even though we may visit a face twice if the neighboring
+      // cells are equally refined, we can only visit each face with
+      // hanging nodes once
+      typename DH::active_cell_iterator cell = dof_handler.begin_active(),
+                                        endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+        // artificial cells can at best neighbor ghost cells, but we're not
+        // interested in these interfaces
+        if (!cell->is_artificial ())
+          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            if (cell->face(face)->has_children())
+              {
+                // first of all, make sure that we treat a case which is
+                // possible, i.e. either no dofs on the face at all or no
+                // anisotropic refinement
+                if (cell->get_fe().dofs_per_face == 0)
+                  continue;
+
+                Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+                       ExcNotImplemented());
+
+                // so now we've found a face of an active cell that has
+                // children. that means that there are hanging nodes here.
+
+                // in any case, faces can have at most two sets of active
+                // fe indices, but here the face can have only one (namely
+                // the same as that from the cell we're sitting on), and
+                // each of the children can have only one as well. check
+                // this
+                Assert (cell->face(face)->n_active_fe_indices() == 1,
+                        ExcInternalError());
+                Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+                        == true,
+                        ExcInternalError());
+                for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                  Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
+                          ExcInternalError());
+
+                // first find out whether we can constrain each of the
+                // subfaces to the mother face. in the lingo of the hp
+                // paper, this would be the simple case. note that we can
+                // short-circuit this decision if the dof_handler doesn't
+                // support hp at all
+                //
+                // ignore all interfaces with artificial cells
+                FiniteElementDomination::Domination
+                mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
+
+                if (DoFHandlerSupportsDifferentFEs<DH>::value == true)
+                  for (unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
+                    if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
+                      mother_face_dominates = mother_face_dominates &
+                                              (cell->get_fe().compare_for_face_domination
+                                               (cell->neighbor_child_on_subface (face, c)->get_fe()));
+
+                switch (mother_face_dominates)
+                  {
+                  case FiniteElementDomination::this_element_dominates:
+                  case FiniteElementDomination::either_element_can_dominate:
+                  {
+                    // Case 1 (the simple case and the only case that can
+                    // happen for non-hp DoFHandlers): The coarse element
+                    // dominates the elements on the subfaces (or they are
+                    // all the same)
+                    //
+                    // so we are going to constrain the DoFs on the face
+                    // children against the DoFs on the face itself
+                    master_dofs.resize (cell->get_fe().dofs_per_face);
+
+                    cell->face(face)->get_dof_indices (master_dofs,
+                                                       cell->active_fe_index ());
+
+                    // Now create constraint matrix for the subfaces and
+                    // assemble it. ignore all interfaces with artificial
+                    // cells because we can only get to such interfaces if
+                    // the current cell is a ghost cell
+                    for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+                      {
+                        if (cell->neighbor_child_on_subface (face, c)->is_artificial())
+                          continue;
+
+                        const typename DH::active_face_iterator
+                        subface = cell->face(face)->child(c);
+
+                        Assert (subface->n_active_fe_indices() == 1,
+                                ExcInternalError());
+
+                        const unsigned int
+                        subface_fe_index = subface->nth_active_fe_index(0);
+
+                        // we sometime run into the situation where for
+                        // example on one big cell we have a FE_Q(1) and on
+                        // the subfaces we have a mixture of FE_Q(1) and
+                        // FE_Nothing. In that case, the face domination is
+                        // either_element_can_dominate for the whole
+                        // collection of subfaces, but on the particular
+                        // subface between FE_Q(1) and FE_Nothing, there
+                        // are no constraints that we need to take care of.
+                        // in that case, just continue
+                        if (cell->get_fe().compare_for_face_domination
+                            (subface->get_fe(subface_fe_index))
+                            ==
+                            FiniteElementDomination::no_requirements)
+                          continue;
+
+                        // Same procedure as for the mother cell. Extract
+                        // the face DoFs from the cell DoFs.
+                        slave_dofs.resize (subface->get_fe(subface_fe_index)
+                                           .dofs_per_face);
+                        subface->get_dof_indices (slave_dofs, subface_fe_index);
+
+                        for (unsigned int i=0; i<slave_dofs.size(); ++i)
+                          Assert (slave_dofs[i] != numbers::invalid_dof_index,
+                                  ExcInternalError());
+
+                        // Now create the element constraint for this
+                        // subface.
+                        //
+                        // As a side remark, one may wonder the following:
+                        // neighbor_child is clearly computed correctly,
+                        // i.e. taking into account face_orientation (just
+                        // look at the implementation of that function).
+                        // however, we don't care about this here, when we
+                        // ask for subface_interpolation on subface c. the
+                        // question rather is: do we have to translate 'c'
+                        // here as well?
+                        //
+                        // the answer is in fact 'no'. if one does that,
+                        // results are wrong: constraints are added twice
+                        // for the same pair of nodes but with differing
+                        // weights. in addition, one can look at the
+                        // deal.II/project_*_03 tests that look at exactly
+                        // this case: there, we have a mesh with at least
+                        // one face_orientation==false and hanging nodes,
+                        // and the results of those tests show that the
+                        // result of projection verifies the approximation
+                        // properties of a finite element onto that mesh
+                        ensure_existence_of_subface_matrix
+                        (cell->get_fe(),
+                         subface->get_fe(subface_fe_index),
+                         c,
+                         subface_interpolation_matrices
+                         [cell->active_fe_index()][subface_fe_index][c]);
+
+                        // Add constraints to global constraint matrix.
+                        filter_constraints (master_dofs,
+                                            slave_dofs,
+                                            *(subface_interpolation_matrices
+                                              [cell->active_fe_index()][subface_fe_index][c]),
+                                            constraints);
+                      }
+
+                    break;
+                  }
+
+                  case FiniteElementDomination::other_element_dominates:
+                  case FiniteElementDomination::neither_element_dominates:
+                  {
+                    // Case 2 (the "complex" case): at least one (the
+                    // neither_... case) of the finer elements or all of
+                    // them (the other_... case) is dominating. See the hp
+                    // paper for a way how to deal with this situation
+                    //
+                    // since this is something that can only happen for hp
+                    // dof handlers, add a check here...
+                    Assert (DoFHandlerSupportsDifferentFEs<DH>::value == true,
+                            ExcInternalError());
+
+                    // we first have to find the finite element that is
+                    // able to generate a space that all the other ones can
+                    // be constrained to
+                    const unsigned int dominating_fe_index
+                      = get_most_dominating_subface_fe_index (cell->face(face));
+
+                    const FiniteElement<dim,spacedim> &dominating_fe
+                      = dof_handler.get_fe()[dominating_fe_index];
+
+                    // check also that it is able to constrain the mother
+                    // face. it should be, or we wouldn't have gotten into
+                    // the branch for the 'complex' case
+                    Assert ((dominating_fe.compare_for_face_domination
+                             (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
+                             == FiniteElementDomination::this_element_dominates)
+                            ||
+                            (dominating_fe.compare_for_face_domination
+                             (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
+                             == FiniteElementDomination::either_element_can_dominate),
+                            ExcInternalError());
+
+
+                    // first get the interpolation matrix from the mother
+                    // to the virtual dofs
+                    Assert (dominating_fe.dofs_per_face <=
+                            cell->get_fe().dofs_per_face,
+                            ExcInternalError());
+
+                    ensure_existence_of_face_matrix
+                    (dominating_fe,
+                     cell->get_fe(),
+                     face_interpolation_matrices
+                     [dominating_fe_index][cell->active_fe_index()]);
+
+                    // split this matrix into master and slave components.
+                    // invert the master component
+                    ensure_existence_of_master_dof_mask
+                    (cell->get_fe(),
+                     dominating_fe,
+                     (*face_interpolation_matrices
+                      [dominating_fe_index]
+                      [cell->active_fe_index()]),
+                     master_dof_masks
+                     [dominating_fe_index]
+                     [cell->active_fe_index()]);
+
+                    ensure_existence_of_split_face_matrix
+                    (*face_interpolation_matrices
+                     [dominating_fe_index][cell->active_fe_index()],
+                     (*master_dof_masks
+                      [dominating_fe_index][cell->active_fe_index()]),
+                     split_face_interpolation_matrices
+                     [dominating_fe_index][cell->active_fe_index()]);
+
+                    const FullMatrix<double> &restrict_mother_to_virtual_master_inv
+                      = (split_face_interpolation_matrices
+                         [dominating_fe_index][cell->active_fe_index()]->first);
+
+                    const FullMatrix<double> &restrict_mother_to_virtual_slave
+                      = (split_face_interpolation_matrices
+                         [dominating_fe_index][cell->active_fe_index()]->second);
+
+                    // now compute the constraint matrix as the product
+                    // between the inverse matrix and the slave part
+                    constraint_matrix.reinit (cell->get_fe().dofs_per_face -
+                                              dominating_fe.dofs_per_face,
+                                              dominating_fe.dofs_per_face);
+                    restrict_mother_to_virtual_slave
+                    .mmult (constraint_matrix,
+                            restrict_mother_to_virtual_master_inv);
+
+                    // then figure out the global numbers of master and
+                    // slave dofs and apply constraints
+                    scratch_dofs.resize (cell->get_fe().dofs_per_face);
+                    cell->face(face)->get_dof_indices (scratch_dofs,
+                                                       cell->active_fe_index ());
+
+                    // split dofs into master and slave components
+                    master_dofs.clear ();
+                    slave_dofs.clear ();
+                    for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
+                      if ((*master_dof_masks
+                           [dominating_fe_index][cell->active_fe_index()])[i] == true)
+                        master_dofs.push_back (scratch_dofs[i]);
+                      else
+                        slave_dofs.push_back (scratch_dofs[i]);
+
+                    AssertDimension (master_dofs.size(), dominating_fe.dofs_per_face);
+                    AssertDimension (slave_dofs.size(),
+                                     cell->get_fe().dofs_per_face - dominating_fe.dofs_per_face);
+
+                    filter_constraints (master_dofs,
+                                        slave_dofs,
+                                        constraint_matrix,
+                                        constraints);
+
+
+
+                    // next we have to deal with the subfaces. do as
+                    // discussed in the hp paper
+                    for (unsigned int sf=0;
+                         sf<cell->face(face)->n_children(); ++sf)
+                      {
+                        // ignore interfaces with artificial cells as well
+                        // as interfaces between ghost cells in 2d
+                        if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
+                            ||
+                            (dim==2 && cell->is_ghost()
+                             &&
+                             cell->neighbor_child_on_subface (face, sf)->is_ghost()))
+                          continue;
+
+                        Assert (cell->face(face)->child(sf)
+                                ->n_active_fe_indices() == 1,
+                                ExcInternalError());
+
+                        const unsigned int subface_fe_index
+                          = cell->face(face)->child(sf)->nth_active_fe_index(0);
+                        const FiniteElement<dim,spacedim> &subface_fe
+                          = dof_handler.get_fe()[subface_fe_index];
+
+                        // first get the interpolation matrix from the
+                        // subface to the virtual dofs
+                        Assert (dominating_fe.dofs_per_face <=
+                                subface_fe.dofs_per_face,
+                                ExcInternalError());
+                        ensure_existence_of_subface_matrix
+                        (dominating_fe,
+                         subface_fe,
+                         sf,
+                         subface_interpolation_matrices
+                         [dominating_fe_index][subface_fe_index][sf]);
+
+                        const FullMatrix<double> &restrict_subface_to_virtual
+                          = *(subface_interpolation_matrices
+                              [dominating_fe_index][subface_fe_index][sf]);
+
+                        constraint_matrix.reinit (subface_fe.dofs_per_face,
+                                                  dominating_fe.dofs_per_face);
+
+                        restrict_subface_to_virtual
+                        .mmult (constraint_matrix,
+                                restrict_mother_to_virtual_master_inv);
+
+                        slave_dofs.resize (subface_fe.dofs_per_face);
+                        cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
+                                                                      subface_fe_index);
+
+                        filter_constraints (master_dofs,
+                                            slave_dofs,
+                                            constraint_matrix,
+                                            constraints);
+                      }
+
+                    break;
+                  }
+
+                  case FiniteElementDomination::no_requirements:
+                    // there are no continuity requirements between the two
+                    // elements. record no constraints
+                    break;
+
+                  default:
+                    // we shouldn't get here
+                    Assert (false, ExcInternalError());
+                  }
+              }
+            else
+              {
+                // this face has no children, but it could still be that it
+                // is shared by two cells that use a different fe index
+                Assert (cell->face(face)
+                        ->fe_index_is_active(cell->active_fe_index()) == true,
+                        ExcInternalError());
+
+                // see if there is a neighbor that is an artificial cell.
+                // in that case, we're not interested in this interface. we
+                // test this case first since artificial cells may not have
+                // an active_fe_index set, etc
+                if (!cell->at_boundary(face)
+                    &&
+                    cell->neighbor(face)->is_artificial())
+                  continue;
+
+                // Only if there is a neighbor with a different
+                // active_fe_index and the same h-level, some action has to
+                // be taken.
+                if ((DoFHandlerSupportsDifferentFEs<DH>::value == true)
+                    &&
+                    !cell->face(face)->at_boundary ()
+                    &&
+                    (cell->neighbor(face)->active_fe_index () !=
+                     cell->active_fe_index ())
+                    &&
+                    (!cell->face(face)->has_children() &&
+                     !cell->neighbor_is_coarser(face) ))
+                  {
+                    const typename DH::level_cell_iterator neighbor = cell->neighbor (face);
+
+                    // see which side of the face we have to constrain
+                    switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
+                      {
+                      case FiniteElementDomination::this_element_dominates:
+                      {
+                        // Get DoFs on dominating and dominated side of the
+                        // face
+                        master_dofs.resize (cell->get_fe().dofs_per_face);
+                        cell->face(face)->get_dof_indices (master_dofs,
+                                                           cell->active_fe_index ());
+
+                        slave_dofs.resize (neighbor->get_fe().dofs_per_face);
+                        cell->face(face)->get_dof_indices (slave_dofs,
+                                                           neighbor->active_fe_index ());
+
+                        // break if the n_master_dofs == 0, because we are
+                        // attempting to constrain to an element that has
+                        // no face dofs
+                        if (master_dofs.size() == 0) break;
+
+                        // make sure the element constraints for this face
+                        // are available
+                        ensure_existence_of_face_matrix
+                        (cell->get_fe(),
+                         neighbor->get_fe(),
+                         face_interpolation_matrices
+                         [cell->active_fe_index()][neighbor->active_fe_index()]);
+
+                        // Add constraints to global constraint matrix.
+                        filter_constraints (master_dofs,
+                                            slave_dofs,
+                                            *(face_interpolation_matrices
+                                              [cell->active_fe_index()]
+                                              [neighbor->active_fe_index()]),
+                                            constraints);
+
+                        break;
+                      }
+
+                      case FiniteElementDomination::other_element_dominates:
+                      {
+                        // we don't do anything here since we will come
+                        // back to this face from the other cell, at which
+                        // time we will fall into the first case clause
+                        // above
+                        break;
+                      }
+
+                      case FiniteElementDomination::either_element_can_dominate:
+                      {
+                        // it appears as if neither element has any
+                        // constraints on its neighbor. this may be because
+                        // neither element has any DoFs on faces at all. or
+                        // that the two elements are actually the same,
+                        // although they happen to run under different
+                        // fe_indices (this is what happens in
+                        // hp/hp_hanging_nodes_01 for example).
+                        //
+                        // another possibility is what happens in crash_13.
+                        // there, we have FESystem(FE_Q(1),FE_DGQ(0)) vs.
+                        // FESystem(FE_Q(1),FE_DGQ(1)). neither of them
+                        // dominates the other.
+                       //
+                       // a final possibility is that we have something like
+                       // FESystem(FE_Q(1),FE_Q(1)) vs
+                       // FESystem(FE_Q(1),FE_Nothing()), see
+                       // hp/fe_nothing_18/19.
+                       //
+                       // in any case, the point is that it doesn't
+                        // matter. there is nothing to do here.
+                        break;
+                      }
+
+                      case FiniteElementDomination::neither_element_dominates:
+                      {
+                        // we don't presently know what exactly to do here.
+                        // it isn't quite clear what exactly we would have
+                        // to do here. sit tight until someone trips over
+                        // the following statement and see what exactly is
+                        // going on
+                        Assert (false, ExcNotImplemented());
+                        break;
+                      }
+
+                      case FiniteElementDomination::no_requirements:
+                      {
+                        // nothing to do here
+                        break;
+                      }
+
+                      default:
+                        // we shouldn't get here
+                        Assert (false, ExcInternalError());
+                      }
+                  }
+              }
+    }
+  }
+
+
+
+
+  template <class DH>
+  void
+  make_hanging_node_constraints (const DH &dof_handler,
+                                 ConstraintMatrix &constraints)
+  {
+    // Decide whether to use the new or old make_hanging_node_constraints
+    // function. If all the FiniteElement or all elements in a FECollection
+    // support the new face constraint matrix, the new code will be used.
+    // Otherwise, the old implementation is used for the moment.
+    if (dof_handler.get_fe().hp_constraints_are_implemented ())
+      internal::
+      make_hp_hanging_node_constraints (dof_handler,
+                                        constraints);
+    else
+      internal::
+      make_oldstyle_hanging_node_constraints (dof_handler,
+                                              constraints,
+                                              dealii::internal::int2type<DH::dimension>());
+  }
+
+
+
+  namespace
+  {
+    // enter constraints for periodicity into the given ConstraintMatrix object.
+    // this function is called when at least one of the two face iterators corresponds
+    // to an active object without further children
+    //
+    // @param transformation A matrix that maps degrees of freedom from one face
+    // to another. If the DoFs on the two faces are supposed to match exactly, then
+    // the matrix so provided will be the identity matrix. if face 2 is once refined
+    // from face 1, then the matrix needs to be the interpolation matrix from a face
+    // to this particular child
+    //
+    // @precondition: face_1 is supposed to be active
+    //
+    // @note As bug #82 ((http://code.google.com/p/dealii/issues/detail?id=82) and the
+    // corresponding testcase bits/periodicity_05 demonstrate, we can occasionally
+    // get into trouble if we already have the constraint x1=x2 and want to insert
+    // x2=x1. we avoid this by skipping an identity constraint if the opposite
+    // constraint already exists
+    template <typename FaceIterator>
+    void
+    set_periodicity_constraints (const FaceIterator                          &face_1,
+                                 const typename identity<FaceIterator>::type &face_2,
+                                 const FullMatrix<double>                    &transformation,
+                                 dealii::ConstraintMatrix                    &constraint_matrix,
+                                 const ComponentMask                         &component_mask,
+                                 const bool                                   face_orientation,
+                                 const bool                                   face_flip,
+                                 const bool                                   face_rotation)
+    {
+      static const int dim      = FaceIterator::AccessorType::dimension;
+      static const int spacedim = FaceIterator::AccessorType::space_dimension;
+
+      // we should be in the case where face_1 is active, i.e. has no children:
+      Assert (!face_1->has_children(),
+              ExcInternalError());
+
+      Assert (face_1->n_active_fe_indices() == 1,
+              ExcInternalError());
+
+      // if face_2 does have children, then we need to iterate over them
+      if (face_2->has_children())
+        {
+          Assert (face_2->n_children() == GeometryInfo<dim>::max_children_per_face,
+                  ExcNotImplemented());
+          const unsigned int dofs_per_face
+            = face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
+          FullMatrix<double> child_transformation (dofs_per_face, dofs_per_face);
+          FullMatrix<double> subface_interpolation (dofs_per_face, dofs_per_face);
+          for (unsigned int c=0; c<face_2->n_children(); ++c)
+            {
+              // get the interpolation matrix recursively from the one that
+              // interpolated from face_1 to face_2 by multiplying from the
+              // left with the one that interpolates from face_2 to
+              // its child
+              face_1->get_fe(face_1->nth_active_fe_index(0))
+              .get_subface_interpolation_matrix (face_1->get_fe(face_1->nth_active_fe_index(0)),
+                                                 c,
+                                                 subface_interpolation);
+              subface_interpolation.mmult (child_transformation, transformation);
+              set_periodicity_constraints(face_1, face_2->child(c),
+                                          child_transformation,
+                                          constraint_matrix, component_mask,
+                                          face_orientation, face_flip, face_rotation);
+            }
+        }
+      else
+        // both faces are active. we need to match the corresponding DoFs of both faces
+        {
+          const unsigned int face_1_index = face_1->nth_active_fe_index(0);
+          const unsigned int face_2_index = face_2->nth_active_fe_index(0);
+          Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_1_index),
+                 ExcMessage ("Matching periodic cells need to use the same finite element"));
+
+          const FiniteElement<dim, spacedim> &fe = face_1->get_fe(face_1_index);
+
+          Assert(component_mask.represents_n_components(fe.n_components()),
+                 ExcMessage ("The number of components in the mask has to be either "
+                             "zero or equal to the number of components in the finite " "element."));
+
+          const unsigned int dofs_per_face = fe.dofs_per_face;
+
+          std::vector<types::global_dof_index> dofs_1(dofs_per_face);
+          std::vector<types::global_dof_index> dofs_2(dofs_per_face);
+
+          face_1->get_dof_indices(dofs_1, face_1_index);
+          face_2->get_dof_indices(dofs_2, face_2_index);
+
+          // Well, this is a hack:
+          //
+          // There is no
+          //   face_to_face_index(face_index,
+          //                      face_orientation,
+          //                      face_flip,
+          //                      face_rotation)
+          // function in FiniteElementData, so we have to use
+          //   face_to_cell_index(face_index, face
+          //                      face_orientation,
+          //                      face_flip,
+          //                      face_rotation)
+          // But this will give us an index on a cell - something we cannot work
+          // with directly. But luckily we can match them back :-]
+
+          std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
+
+          // Build up a cell to face index for face_2:
+          for (unsigned int i = 0; i < dofs_per_face; ++i)
+            {
+              const unsigned int cell_index = fe.face_to_cell_index(i, 0, /* It doesn't really matter, just assume
+                                                                           * we're on the first face...
+                                                                           */
+                                                                    true, false, false // default orientation
+                                                                   );
+              cell_to_rotated_face_index[cell_index] = i;
+            }
+
+          // loop over all dofs on face 2 and constrain them again the ones on face 1
+          for (unsigned int i=0; i<dofs_per_face; ++i)
+            if (!constraint_matrix.is_constrained(dofs_2[i]))
+              if ((component_mask.n_selected_components(fe.n_components())
+                   == fe.n_components())
+                  ||
+                  component_mask[fe.face_system_to_component_index(i).first])
+                {
+                  // as mentioned in the comment above this function, we need
+                  // to be careful about treating identity constraints differently.
+                  // consequently, find out whether this dof 'i' will be
+                  // identity constrained
+                  //
+                  // to check whether this is the case, first see whether there are
+                  // any weights other than 0 and 1, then in a first stage make sure
+                  // that if so there is only one weight equal to 1
+                  bool is_identity_constrained = true;
+                  for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                    if (((transformation(i,jj) == 0) || (transformation(i,jj) == 1)) == false)
+                      {
+                        is_identity_constrained = false;
+                        break;
+                      }
+                  unsigned int identity_constraint_target = numbers::invalid_unsigned_int;
+                  if (is_identity_constrained == true)
+                    {
+                      bool one_identity_found = false;
+                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                        if (transformation(i,jj) == 1)
+                          {
+                            if (one_identity_found == false)
+                              {
+                                one_identity_found = true;
+                                identity_constraint_target = jj;
+                              }
+                            else
+                              {
+                                is_identity_constrained = false;
+                                identity_constraint_target = numbers::invalid_unsigned_int;
+                                break;
+                              }
+                          }
+                    }
+
+                  // now treat constraints, either as an equality constraint or
+                  // as a sequence of constraints
+                  if (is_identity_constrained == true)
+                    {
+                      // Query the correct face_index on face_2 respecting the given
+                      // orientation:
+                      const unsigned int j =
+                        cell_to_rotated_face_index[fe.face_to_cell_index(identity_constraint_target,
+                            0, /* It doesn't really matter, just assume
+                           * we're on the first face...
+                           */
+                                                                         face_orientation, face_flip, face_rotation)];
+
+                      // if the two aren't already identity constrained (whichever way
+                      // around, then enter the constraint. otherwise there is nothing
+                      // for us still to do
+                      if (constraint_matrix.are_identity_constrained(dofs_2[i], dofs_1[i]) == false)
+                        {
+                          constraint_matrix.add_line(dofs_2[i]);
+                          constraint_matrix.add_entry(dofs_2[i], dofs_1[j], 1);
+                        }
+                    }
+                  else
+                    {
+                      // this is just a regular constraint. enter it piece by piece
+                      constraint_matrix.add_line(dofs_2[i]);
+                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                        {
+                          // Query the correct face_index on face_2 respecting the given
+                          // orientation:
+                          const unsigned int j =
+                            cell_to_rotated_face_index[fe.face_to_cell_index(jj, 0, /* It doesn't really matter, just assume
+                               * we're on the first face...
+                               */
+                                                                             face_orientation, face_flip, face_rotation)];
+
+                          // And finally constrain the two DoFs respecting component_mask:
+                          if (transformation(i,jj) != 0)
+                            constraint_matrix.add_entry(dofs_2[i], dofs_1[j],
+                                                        transformation(i,jj));
+                        }
+                    }
+                }
+        }
+    }
+  }
+
+
+  template <typename FaceIterator>
+  void
+  make_periodicity_constraints (const FaceIterator                          &face_1,
+                                const typename identity<FaceIterator>::type &face_2,
+                                dealii::ConstraintMatrix                    &constraint_matrix,
+                                const ComponentMask                         &component_mask,
+                                const bool                                   face_orientation,
+                                const bool                                   face_flip,
+                                const bool                                   face_rotation)
+  {
+    static const int dim = FaceIterator::AccessorType::dimension;
+
+    Assert( (dim != 1) ||
+            (face_orientation == true &&
+             face_flip == false &&
+             face_rotation == false),
+            ExcMessage ("The supplied orientation "
+                        "(face_orientation, face_flip, face_rotation) "
+                        "is invalid for 1D"));
+
+    Assert( (dim != 2) ||
+            (face_orientation == true &&
+             face_rotation == false),
+            ExcMessage ("The supplied orientation "
+                        "(face_orientation, face_flip, face_rotation) "
+                        "is invalid for 2D"));
+
+    Assert(face_1 != face_2,
+           ExcMessage ("face_1 and face_2 are equal! Cannot constrain DoFs "
+                       "on the very same face"));
+
+    Assert(face_1->at_boundary() && face_2->at_boundary(),
+           ExcMessage ("Faces for periodicity constraints must be on the boundary"));
+
+
+    // A lookup table on how to go through the child faces depending on the
+    // orientation:
+
+    static const int lookup_table_2d[2][2] =
+    {
+      //          flip:
+      {0, 1}, //  false
+      {1, 0}, //  true
+    };
+
+    static const int lookup_table_3d[2][2][2][4] =
+    {
+      //                    orientation flip  rotation
+      { { {0, 2, 1, 3}, //  false       false false
+          {2, 3, 0, 1}, //  false       false true
+        },
+        { {3, 1, 2, 0}, //  false       true  false
+          {1, 0, 3, 2}, //  false       true  true
+        },
+      },
+      { { {0, 1, 2, 3}, //  true        false false
+          {1, 3, 0, 2}, //  true        false true
+        },
+        { {3, 2, 1, 0}, //  true        true  false
+          {2, 0, 3, 1}, //  true        true  true
+        },
+      },
+    };
+
+    // In the case that both faces have children, we loop over all
+    // children and apply make_periodicty_constrains recursively:
+    if (face_1->has_children() && face_2->has_children())
+      {
+        Assert(face_1->n_children() == GeometryInfo<dim>::max_children_per_face &&
+               face_2->n_children() == GeometryInfo<dim>::max_children_per_face,
+               ExcNotImplemented());
+
+        for (unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face; ++i)
+          {
+            // Lookup the index for the second face
+            unsigned int j;
+            switch (dim)
+              {
+              case 2:
+                j = lookup_table_2d[face_flip][i];
+                break;
+              case 3:
+                j = lookup_table_3d[face_orientation][face_flip][face_rotation][i];
+                break;
+              default:
+                AssertThrow(false, ExcNotImplemented());
+              }
+
+            make_periodicity_constraints (face_1->child(i),
+                                          face_2->child(j),
+                                          constraint_matrix,
+                                          component_mask,
+                                          face_orientation,
+                                          face_flip,
+                                          face_rotation);
+          }
+      }
+    else
+      // otherwise at least one of the two faces is active and
+      // we need to enter the constraints
+      {
+        if (face_2->has_children() == false)
+          set_periodicity_constraints(face_2, face_1,
+                                      FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face)),
+                                      constraint_matrix,
+                                      component_mask,
+                                      face_orientation, face_flip, face_rotation);
+        else
+          set_periodicity_constraints(face_1, face_2,
+                                      FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face)),
+                                      constraint_matrix,
+                                      component_mask,
+                                      face_orientation, face_flip, face_rotation);
+      }
+  }
+
+
+
+  template<typename DH>
+  void
+  make_periodicity_constraints (const DH                       &dof_handler,
+                                const types::boundary_id       b_id1,
+                                const types::boundary_id       b_id2,
+                                const int                      direction,
+                                dealii::ConstraintMatrix       &constraint_matrix,
+                                const ComponentMask            &component_mask)
+  {
+    Tensor<1,DH::space_dimension> dummy;
+    make_periodicity_constraints (dof_handler,
+                                  b_id1,
+                                  b_id2,
+                                  direction,
+                                  dummy,
+                                  constraint_matrix,
+                                  component_mask);
+  }
+
+
+
+  template<typename DH>
+  void
+  make_periodicity_constraints (const DH                  &dof_handler,
+                                const types::boundary_id  b_id1,
+                                const types::boundary_id  b_id2,
+                                const int                 direction,
+                                dealii::Tensor<1,DH::space_dimension> &offset,
+                                dealii::ConstraintMatrix  &constraint_matrix,
+                                const ComponentMask       &component_mask)
+  {
+    static const int space_dim = DH::space_dimension;
+    Assert (0<=direction && direction<space_dim,
+            ExcIndexRange (direction, 0, space_dim));
+
+#if defined(DEBUG) && defined(DEAL_II_WITH_P4EST)
+    // Check whether we run on a non parallel mesh or on a
+    // parallel::distributed::Triangulation in serial
+    {
+      typedef parallel::distributed::Triangulation<DH::dimension,DH::space_dimension> PTRIA;
+      const PTRIA *ptria_p = dynamic_cast<const PTRIA *> (&dof_handler.get_tria());
+      Assert ((ptria_p == 0 || Utilities::MPI::n_mpi_processes(ptria_p->get_communicator()) == 1),
+              ExcMessage ("This function can not be used with distributed triangulations."
+                          "See the documentation for more information."));
+    }
+#endif
+
+    Assert (b_id1 != b_id2,
+            ExcMessage ("The boundary indicators b_id1 and b_id2 must be"
+                        "different to denote different boundaries."));
+
+    typedef typename DH::face_iterator FaceIterator;
+    typedef std::map<FaceIterator, std::pair<FaceIterator, std::bitset<3> > > FaceMap;
+
+    // Collect matching periodic cells on the coarsest level:
+    FaceMap matched_cells =
+      GridTools::collect_periodic_face_pairs(dof_handler,
+                                             b_id1, b_id2,
+                                             direction, offset);
+
+    // And apply the low level make_periodicity_constraints function to
+    // every matching pair:
+    for (typename FaceMap::iterator it = matched_cells.begin();
+         it != matched_cells.end(); ++it)
+      {
+        typedef typename DH::face_iterator FaceIterator;
+        const FaceIterator &face_1 = it->first;
+        const FaceIterator &face_2 = it->second.first;
+        const std::bitset<3> &orientation = it->second.second;
+
+        Assert(face_1->at_boundary() && face_2->at_boundary(),
+               ExcInternalError());
+
+        Assert (face_1->boundary_indicator() == b_id1 &&
+                face_2->boundary_indicator() == b_id2,
+                ExcInternalError());
+
+        Assert (face_1 != face_2,
+                ExcInternalError());
+
+        make_periodicity_constraints(face_1,
+                                     face_2,
+                                     constraint_matrix,
+                                     component_mask,
+                                     orientation[0],
+                                     orientation[1],
+                                     orientation[2]);
+      }
+  }
+
+
+
+  template<typename DH>
+  void
+  make_periodicity_constraints (const DH                       &dof_handler,
+                                const types::boundary_id       b_id,
+                                const int                      direction,
+                                dealii::ConstraintMatrix       &constraint_matrix,
+                                const ComponentMask            &component_mask)
+  {
+    Tensor<1,DH::space_dimension> dummy;
+    make_periodicity_constraints (dof_handler,
+                                  b_id,
+                                  direction,
+                                  dummy,
+                                  constraint_matrix,
+                                  component_mask);
+  }
+
+
+
+  template<typename DH>
+  void
+  make_periodicity_constraints (const DH                  &dof_handler,
+                                const types::boundary_id  b_id,
+                                const int                 direction,
+                                dealii::Tensor<1,DH::space_dimension> &offset,
+                                dealii::ConstraintMatrix  &constraint_matrix,
+                                const ComponentMask       &component_mask)
+  {
+    static const int dim = DH::dimension;
+    static const int space_dim = DH::space_dimension;
+
+    Assert (0<=direction && direction<space_dim,
+            ExcIndexRange (direction, 0, space_dim));
+
+    Assert(dim == space_dim,
+           ExcNotImplemented());
+
+#if defined(DEBUG) && defined(DEAL_II_WITH_P4EST)
+    // Check whether we run on a non parallel mesh or on a
+    // parallel::distributed::Triangulation in serial
+    {
+      typedef typename parallel::distributed::Triangulation<DH::dimension,DH::space_dimension> PTRIA;
+      const PTRIA *ptria_p = dynamic_cast<const PTRIA *> (&dof_handler.get_tria());
+      Assert ((ptria_p == 0 || Utilities::MPI::n_mpi_processes(ptria_p->get_communicator()) == 1),
+              ExcMessage ("This function can not be used with distributed triangulations."
+                          "See the documentation for more information."));
+    }
+#endif
+
+    typedef typename DH::face_iterator FaceIterator;
+    typedef std::map<FaceIterator, FaceIterator> FaceMap;
+
+    // Collect matching periodic cells on the coarsest level:
+    FaceMap matched_cells =
+      GridTools::collect_periodic_face_pairs(dof_handler,
+                                             b_id,
+                                             direction, offset);
+
+    // And apply the low level make_periodicity_constraints function to
+    // every matching pair:
+    for (typename FaceMap::iterator it = matched_cells.begin();
+         it != matched_cells.end(); ++it)
+      {
+        typedef typename DH::face_iterator FaceIterator;
+        const FaceIterator &face_1 = it->first;
+        const FaceIterator &face_2 = it->second;
+
+        Assert(face_1->at_boundary() && face_2->at_boundary(),
+               ExcInternalError());
+
+        Assert (face_1->boundary_indicator() == b_id &&
+                face_2->boundary_indicator() == b_id,
+                ExcInternalError());
+
+        Assert (face_1 != face_2,
+                ExcInternalError());
+
+        make_periodicity_constraints(face_1,
+                                     face_2,
+                                     constraint_matrix,
+                                     component_mask
+                                     /* standard orientation */);
+      }
+  }
+
+
+
+  namespace internal
+  {
+    namespace
+    {
+      /**
+       * This is a function that is called by the _2 function and that
+       * operates on a range of cells only. It is used to split up the
+       * whole range of cells into chunks which are then worked on in
+       * parallel, if multithreading is available.
+       */
+      template <int dim, int spacedim>
+      void
+      compute_intergrid_weights_3 (
+        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
+        const unsigned int                  coarse_component,
+        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+        const std::vector<dealii::Vector<double> > &parameter_dofs,
+        const std::vector<types::global_dof_index>             &weight_mapping,
+        std::vector<std::map<types::global_dof_index, float> > &weights,
+        const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &begin,
+        const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &end)
+      {
+        // aliases to the finite elements used by the dof handlers:
+        const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe();
+
+        // for each cell on the parameter grid: find out which degrees of
+        // freedom on the fine grid correspond in which way to the degrees
+        // of freedom on the parameter grid
+        //
+        // since for continuous FEs some dofs exist on more than one cell,
+        // we have to track which ones were already visited. the problem is
+        // that if we visit a dof first on one cell and compute its weight
+        // with respect to some global dofs to be non-zero, and later visit
+        // the dof again on another cell and (since we are on another cell)
+        // recompute the weights with respect to the same dofs as above to
+        // be zero now, we have to preserve them. we therefore overwrite
+        // all weights if they are nonzero and do not enforce zero weights
+        // since that might be only due to the fact that we are on another
+        // cell.
+        //
+        // example:
+        // coarse grid
+        //  |     |     |
+        //  *-----*-----*
+        //  | cell|cell |
+        //  |  1  |  2  |
+        //  |     |     |
+        //  0-----1-----*
+        //
+        // fine grid
+        //  |  |  |  |  |
+        //  *--*--*--*--*
+        //  |  |  |  |  |
+        //  *--*--*--*--*
+        //  |  |  |  |  |
+        //  *--x--y--*--*
+        //
+        // when on cell 1, we compute the weights of dof 'x' to be 1/2 from
+        // parameter dofs 0 and 1, respectively. however, when later we are
+        // on cell 2, we again compute the prolongation of shape function 1
+        // restricted to cell 2 to the globla grid and find that the weight
+        // of global dof 'x' now is zero. however, we should not overwrite
+        // the old value.
+        //
+        // we therefore always only set nonzero values. why adding up is
+        // not useful: dof 'y' would get weight 1 from parameter dof 1 on
+        // both cells 1 and 2, but the correct weight is nevertheless only
+        // 1.
+
+        // vector to hold the representation of a single degree of freedom
+        // on the coarse grid (for the selected fe) on the fine grid
+        const types::global_dof_index n_fine_dofs = weight_mapping.size();
+        dealii::Vector<double> global_parameter_representation (n_fine_dofs);
+
+        typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator cell;
+        std::vector<types::global_dof_index> parameter_dof_indices (coarse_fe.dofs_per_cell);
+
+        for (cell=begin; cell!=end; ++cell)
+          {
+            // get the global indices of the parameter dofs on this
+            // parameter grid cell
+            cell->get_dof_indices (parameter_dof_indices);
+
+            // loop over all dofs on this cell and check whether they are
+            // interesting for us
+            for (unsigned int local_dof=0;
+                 local_dof<coarse_fe.dofs_per_cell;
+                 ++local_dof)
+              if (coarse_fe.system_to_component_index(local_dof).first
+                  ==
+                  coarse_component)
+                {
+                  // the how-many-th parameter is this on this cell?
+                  const unsigned int local_parameter_dof
+                    = coarse_fe.system_to_component_index(local_dof).second;
+
+                  global_parameter_representation = 0;
+
+                  // distribute the representation of
+                  // @p{local_parameter_dof} on the parameter grid cell
+                  // @p{cell} to the global data space
+                  coarse_to_fine_grid_map[cell]->
+                  set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
+                                                   global_parameter_representation);
+                  // now that we've got the global representation of each
+                  // parameter dof, we've only got to clobber the non-zero
+                  // entries in that vector and store the result
+                  //
+                  // what we have learned: if entry @p{i} of the global
+                  // vector holds the value @p{v[i]}, then this is the
+                  // weight with which the present dof contributes to
+                  // @p{i}. there may be several such @p{i}s and their
+                  // weights' sum should be one. Then, @p{v[i]} should be
+                  // equal to @p{\sum_j w_{ij} p[j]} with @p{p[j]} be the
+                  // values of the degrees of freedom on the coarse grid.
+                  // we can thus compute constraints which link the degrees
+                  // of freedom @p{v[i]} on the fine grid to those on the
+                  // coarse grid, @p{p[j]}. Now to use these as real
+                  // constraints, rather than as additional equations, we
+                  // have to identify representants among the @p{i} for
+                  // each @p{j}. this will be done by simply taking the
+                  // first @p{i} for which @p{w_{ij}==1}.
+                  //
+                  // guard modification of the weights array by a Mutex.
+                  // since it should happen rather rarely that there are
+                  // several threads operating on different intergrid
+                  // weights, have only one mutex for all of them
+                  static Threads::Mutex mutex;
+                  Threads::Mutex::ScopedLock lock (mutex);
+                  for (types::global_dof_index i=0; i<global_parameter_representation.size(); ++i)
+                    // set this weight if it belongs to a parameter dof.
+                    if (weight_mapping[i] != numbers::invalid_dof_index)
+                      {
+                        // only overwrite old value if not by zero
+                        if (global_parameter_representation(i) != 0)
+                          {
+                            const types::global_dof_index wi = parameter_dof_indices[local_dof],
+                                                          wj = weight_mapping[i];
+                            weights[wi][wj] = global_parameter_representation(i);
+                          };
+                      }
+                    else
+                      Assert (global_parameter_representation(i) == 0,
+                              ExcInternalError());
+                }
+          }
+      }
+
+
+      /**
+       * This is a helper function that is used in the computation of
+       * integrid constraints. See the function for a thorough description
+       * of how it works.
+       */
+      template <int dim, int spacedim>
+      void
+      compute_intergrid_weights_2 (
+        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
+        const unsigned int                  coarse_component,
+        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+        const std::vector<dealii::Vector<double> > &parameter_dofs,
+        const std::vector<types::global_dof_index>             &weight_mapping,
+        std::vector<std::map<types::global_dof_index,float> > &weights)
+      {
+        // simply distribute the range of cells to different threads
+        typedef typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
+        std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
+        cell_intervals = Threads::split_range<active_cell_iterator> (coarse_grid.begin_active(),
+                         coarse_grid.end(),
+                         multithread_info.n_default_threads);
+
+        // TODO: use WorkStream here
+
+        Threads::TaskGroup<> tasks;
+        void (*fun_ptr) (const dealii::DoFHandler<dim,spacedim> &,
+                         const unsigned int                  ,
+                         const InterGridMap<dealii::DoFHandler<dim,spacedim> > &,
+                         const std::vector<dealii::Vector<double> > &,
+                         const std::vector<types::global_dof_index> &,
+                         std::vector<std::map<types::global_dof_index, float> > &,
+                         const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &,
+                         const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &)
+          = &compute_intergrid_weights_3<dim>;
+        for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
+          tasks += Threads::new_task (fun_ptr,
+                                      coarse_grid, coarse_component,
+                                      coarse_to_fine_grid_map, parameter_dofs,
+                                      weight_mapping, weights,
+                                      cell_intervals[i].first,
+                                      cell_intervals[i].second);
+
+        // wait for the tasks to finish
+        tasks.join_all ();
+      }
+
+
+
+      /**
+       * This is a helper function that is used in the computation of
+       * integrid constraints. See the function for a thorough description
+       * of how it works.
+       */
+      template <int dim, int spacedim>
+      unsigned int
+      compute_intergrid_weights_1 (
+        const dealii::DoFHandler<dim,spacedim>              &coarse_grid,
+        const unsigned int                  coarse_component,
+        const dealii::DoFHandler<dim,spacedim>              &fine_grid,
+        const unsigned int                  fine_component,
+        const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+        std::vector<std::map<types::global_dof_index, float> > &weights,
+        std::vector<types::global_dof_index>                   &weight_mapping)
+      {
+        // aliases to the finite elements used by the dof handlers:
+        const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe(),
+                                           &fine_fe   = fine_grid.get_fe();
+
+        // global numbers of dofs
+        const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs(),
+                                      n_fine_dofs   = fine_grid.n_dofs();
+
+        // local numbers of dofs
+        const unsigned int fine_dofs_per_cell   = fine_fe.dofs_per_cell;
+
+        // alias the number of dofs per cell belonging to the
+        // coarse_component which is to be the restriction of the fine
+        // grid:
+        const unsigned int coarse_dofs_per_cell_component
+          = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell;
+
+
+        // Try to find out whether the grids stem from the same coarse
+        // grid. This is a rather crude test, but better than nothing
+        Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0),
+                ExcGridsDontMatch());
+
+        // check whether the map correlates the right objects
+        Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
+                ExcGridsDontMatch ());
+        Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
+                ExcGridsDontMatch ());
+
+
+        // check whether component numbers are valid
+        AssertIndexRange (coarse_component,coarse_fe.n_components());
+        AssertIndexRange (fine_component, fine_fe.n_components());
+
+        // check whether respective finite elements are equal
+        Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first)
+                ==
+                fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
+                ExcFiniteElementsDontMatch());
+
+#ifdef DEBUG
+        // if in debug mode, check whether the coarse grid is indeed
+        // coarser everywhere than the fine grid
+        for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+             cell=coarse_grid.begin_active();
+             cell != coarse_grid.end(); ++cell)
+          Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
+                  ExcGridNotCoarser());
+#endif
+
+        /*
+         * From here on: the term `parameter' refers to the selected
+         * component on the coarse grid and its analogon on the fine grid.
+         * The naming of variables containing this term is due to the fact
+         * that `selected_component' is longer, but also due to the fact
+         * that the code of this function was initially written for a
+         * program where the component which we wanted to match between
+         * grids was actually the `parameter' variable.
+         *
+         * Likewise, the terms `parameter grid' and `state grid' refer to
+         * the coarse and fine grids, respectively.
+         *
+         * Changing the names of variables would in principle be a good
+         * idea, but would not make things simpler and would be another
+         * source of errors. If anyone feels like doing so: patches would
+         * be welcome!
+         */
+
+
+
+        // set up vectors of cell-local data; each vector represents one
+        // degree of freedom of the coarse-grid variable in the fine-grid
+        // element
+        std::vector<dealii::Vector<double> >
+        parameter_dofs (coarse_dofs_per_cell_component,
+                        dealii::Vector<double>(fine_dofs_per_cell));
+        // for each coarse dof: find its position within the fine element
+        // and set this value to one in the respective vector (all other
+        // values are zero by construction)
+        for (unsigned int local_coarse_dof=0;
+             local_coarse_dof<coarse_dofs_per_cell_component;
+             ++local_coarse_dof)
+          for (unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
+            if (fine_fe.system_to_component_index(fine_dof)
+                ==
+                std::make_pair (fine_component, local_coarse_dof))
+              {
+                parameter_dofs[local_coarse_dof](fine_dof) = 1.;
+                break;
+              };
+
+
+        // find out how many DoFs there are on the grids belonging to the
+        // components we want to match
+        unsigned int n_parameters_on_fine_grid=0;
+        if (true)
+          {
+            // have a flag for each dof on the fine grid and set it to true
+            // if this is an interesting dof. finally count how many true's
+            // there
+            std::vector<bool> dof_is_interesting (fine_grid.n_dofs(), false);
+            std::vector<types::global_dof_index>  local_dof_indices (fine_fe.dofs_per_cell);
+
+            for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+                 cell=fine_grid.begin_active();
+                 cell!=fine_grid.end(); ++cell)
+              {
+                cell->get_dof_indices (local_dof_indices);
+                for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
+                  if (fine_fe.system_to_component_index(i).first == fine_component)
+                    dof_is_interesting[local_dof_indices[i]] = true;
+              };
+
+            n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
+                                                    dof_is_interesting.end(),
+                                                    true);
+          };
+
+
+        // set up the weights mapping
+        weights.clear ();
+        weights.resize (n_coarse_dofs);
+
+        weight_mapping.clear ();
+        weight_mapping.resize (n_fine_dofs, numbers::invalid_dof_index);
+
+        if (true)
+          {
+            std::vector<types::global_dof_index> local_dof_indices(fine_fe.dofs_per_cell);
+            unsigned int next_free_index=0;
+            for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+                 cell=fine_grid.begin_active();
+                 cell != fine_grid.end(); ++cell)
+              {
+                cell->get_dof_indices (local_dof_indices);
+                for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
+                  // if this DoF is a parameter dof and has not yet been
+                  // numbered, then do so
+                  if ((fine_fe.system_to_component_index(i).first == fine_component) &&
+                      (weight_mapping[local_dof_indices[i]] == numbers::invalid_dof_index))
+                    {
+                      weight_mapping[local_dof_indices[i]] = next_free_index;
+                      ++next_free_index;
+                    };
+              };
+
+            Assert (next_free_index == n_parameters_on_fine_grid,
+                    ExcInternalError());
+          };
+
+
+        // for each cell on the parameter grid: find out which degrees of
+        // freedom on the fine grid correspond in which way to the degrees
+        // of freedom on the parameter grid
+        //
+        // do this in a separate function to allow for multithreading
+        // there. see this function also if you want to read more
+        // information on the algorithm used.
+        compute_intergrid_weights_2 (coarse_grid, coarse_component,
+                                     coarse_to_fine_grid_map, parameter_dofs,
+                                     weight_mapping, weights);
+
+
+        // ok, now we have all weights for each dof on the fine grid. if in
+        // debug mode lets see if everything went smooth, i.e. each dof has
+        // sum of weights one
+        //
+        // in other words this means that if the sum of all shape functions
+        // on the parameter grid is one (which is always the case), then
+        // the representation on the state grid should be as well (division
+        // of unity)
+        //
+        // if the parameter grid has more than one component, then the
+        // respective dofs of the other components have sum of weights
+        // zero, of course. we do not explicitly ask which component a dof
+        // belongs to, but this at least tests some errors
+#ifdef DEBUG
+        for (unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
+          {
+            double sum=0;
+            for (types::global_dof_index row=0; row<n_coarse_dofs; ++row)
+              if (weights[row].find(col) != weights[row].end())
+                sum += weights[row][col];
+            Assert ((std::fabs(sum-1) < 1.e-12) ||
+                    ((coarse_fe.n_components()>1) && (sum==0)), ExcInternalError());
+          };
+#endif
+
+
+        return n_parameters_on_fine_grid;
+      }
+
+
+    }
+  }
+
+
+
+  template <int dim, int spacedim>
+  void
+  compute_intergrid_constraints (
+    const DoFHandler<dim,spacedim>              &coarse_grid,
+    const unsigned int                  coarse_component,
+    const DoFHandler<dim,spacedim>              &fine_grid,
+    const unsigned int                  fine_component,
+    const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+    ConstraintMatrix                   &constraints)
+  {
+    // store the weights with which a dof on the parameter grid contributes
+    // to a dof on the fine grid. see the long doc below for more info
+    //
+    // allocate as many rows as there are parameter dofs on the coarse grid
+    // and as many columns as there are parameter dofs on the fine grid.
+    //
+    // weight_mapping is used to map the global (fine grid) parameter dof
+    // indices to the columns
+    //
+    // in the original implementation, the weights array was actually of
+    // FullMatrix<double> type. this wasted huge amounts of memory, but was
+    // fast. nonetheless, since the memory consumption was quadratic in the
+    // number of degrees of freedom, this was not very practical, so we now
+    // use a vector of rows of the matrix, and in each row a vector of
+    // pairs (colnum,value). this seems like the best tradeoff between
+    // memory and speed, as it is now linear in memory and still fast
+    // enough.
+    //
+    // to save some memory and since the weights are usually (negative)
+    // powers of 2, we choose the value type of the matrix to be @p{float}
+    // rather than @p{double}.
+    std::vector<std::map<types::global_dof_index, float> > weights;
+
+    // this is this mapping. there is one entry for each dof on the fine
+    // grid; if it is a parameter dof, then its value is the column in
+    // weights for that parameter dof, if it is any other dof, then its
+    // value is -1, indicating an error
+    std::vector<types::global_dof_index> weight_mapping;
+
+    const unsigned int n_parameters_on_fine_grid
+      = internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
+                                               fine_grid, fine_component,
+                                               coarse_to_fine_grid_map,
+                                               weights, weight_mapping);
+
+    // global numbers of dofs
+    const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs(),
+                                  n_fine_dofs   = fine_grid.n_dofs();
+
+
+    // get an array in which we store which dof on the coarse grid is a
+    // parameter and which is not
+    std::vector<bool> coarse_dof_is_parameter (coarse_grid.n_dofs());
+    if (true)
+      {
+        std::vector<bool> mask (coarse_grid.get_fe().n_components(),
+                                false);
+        mask[coarse_component] = true;
+        extract_dofs (coarse_grid, ComponentMask(mask), coarse_dof_is_parameter);
+      }
+
+    // now we know that the weights in each row constitute a constraint.
+    // enter this into the constraints object
+    //
+    // first task: for each parameter dof on the parameter grid, find a
+    // representant on the fine, global grid. this is possible since we use
+    // conforming finite element. we take this representant to be the first
+    // element in this row with weight identical to one. the representant
+    // will become an unconstrained degree of freedom, while all others
+    // will be constrained to this dof (and possibly others)
+    std::vector<types::global_dof_index> representants(n_coarse_dofs, numbers::invalid_dof_index);
+    for (types::global_dof_index parameter_dof=0; parameter_dof<n_coarse_dofs;
+         ++parameter_dof)
+      if (coarse_dof_is_parameter[parameter_dof] == true)
+        {
+          // if this is the line of a parameter dof on the coarse grid,
+          // then it should have at least one dependent node on the fine
+          // grid
+          Assert (weights[parameter_dof].size() > 0, ExcInternalError());
+
+          // find the column where the representant is mentioned
+          std::map<types::global_dof_index,float>::const_iterator i = weights[parameter_dof].begin();
+          for (; i!=weights[parameter_dof].end(); ++i)
+            if (i->second == 1)
+              break;
+          Assert (i!=weights[parameter_dof].end(), ExcInternalError());
+          const types::global_dof_index column = i->first;
+
+          // now we know in which column of weights the representant is,
+          // but we don't know its global index. get it using the inverse
+          // operation of the weight_mapping
+          types::global_dof_index global_dof=0;
+          for (; global_dof<weight_mapping.size(); ++global_dof)
+            if (weight_mapping[global_dof] == static_cast<types::global_dof_index>(column))
+              break;
+          Assert (global_dof < weight_mapping.size(), ExcInternalError());
+
+          // now enter the representants global index into our list
+          representants[parameter_dof] = global_dof;
+        }
+      else
+        {
+          // consistency check: if this is no parameter dof on the coarse
+          // grid, then the respective row must be empty!
+          Assert (weights[parameter_dof].size() == 0, ExcInternalError());
+        };
+
+
+
+    // note for people that want to optimize this function: the largest
+    // part of the computing time is spent in the following, rather
+    // innocent block of code. basically, it must be the
+    // ConstraintMatrix::add_entry call which takes the bulk of the time,
+    // but it is not known to the author how to make it faster...
+    std::vector<std::pair<types::global_dof_index,double> > constraint_line;
+    for (types::global_dof_index global_dof=0; global_dof<n_fine_dofs; ++global_dof)
+      if (weight_mapping[global_dof] != numbers::invalid_dof_index)
+        // this global dof is a parameter dof, so it may carry a constraint
+        // note that for each global dof, the sum of weights shall be one,
+        // so we can find out whether this dof is constrained in the
+        // following way: if the only weight in this row is a one, and the
+        // representant for the parameter dof of the line in which this one
+        // is is the present dof, then we consider this dof to be
+        // unconstrained. otherwise, all other dofs are constrained
+        {
+          const types::global_dof_index col = weight_mapping[global_dof];
+          Assert (col < n_parameters_on_fine_grid, ExcInternalError());
+
+          types::global_dof_index first_used_row=0;
+
+          {
+            Assert (weights.size() > 0, ExcInternalError());
+            std::map<types::global_dof_index,float>::const_iterator
+            col_entry = weights[0].end();
+            for (; first_used_row<n_coarse_dofs; ++first_used_row)
+              {
+                col_entry = weights[first_used_row].find(col);
+                if (col_entry != weights[first_used_row].end())
+                  break;
+              }
+
+            Assert (col_entry != weights[first_used_row].end(), ExcInternalError());
+
+            if ((col_entry->second == 1) &&
+                (representants[first_used_row] == global_dof))
+              // dof unconstrained or constrained to itself (in case this
+              // cell is mapped to itself, rather than to children of
+              // itself)
+              continue;
+          }
+
+
+          // otherwise enter all constraints
+          constraints.add_line (global_dof);
+
+          constraint_line.clear ();
+          for (types::global_dof_index row=first_used_row; row<n_coarse_dofs; ++row)
+            {
+              const std::map<types::global_dof_index,float>::const_iterator
+              j = weights[row].find(col);
+              if ((j != weights[row].end()) && (j->second != 0))
+                constraint_line.push_back (std::pair<types::global_dof_index,double>(representants[row],
+                                           j->second));
+            };
+
+          constraints.add_entries (global_dof, constraint_line);
+        };
+  }
+
+
+
+  template <int dim, int spacedim>
+  void
+  compute_intergrid_transfer_representation (
+    const DoFHandler<dim,spacedim>              &coarse_grid,
+    const unsigned int                  coarse_component,
+    const DoFHandler<dim,spacedim>              &fine_grid,
+    const unsigned int                  fine_component,
+    const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+    std::vector<std::map<types::global_dof_index, float> > &transfer_representation)
+  {
+    // store the weights with which a dof on the parameter grid contributes
+    // to a dof on the fine grid. see the long doc below for more info
+    //
+    // allocate as many rows as there are parameter dofs on the coarse grid
+    // and as many columns as there are parameter dofs on the fine grid.
+    //
+    // weight_mapping is used to map the global (fine grid) parameter dof
+    // indices to the columns
+    //
+    // in the original implementation, the weights array was actually of
+    // FullMatrix<double> type. this wasted huge amounts of memory, but was
+    // fast. nonetheless, since the memory consumption was quadratic in the
+    // number of degrees of freedom, this was not very practical, so we now
+    // use a vector of rows of the matrix, and in each row a vector of
+    // pairs (colnum,value). this seems like the best tradeoff between
+    // memory and speed, as it is now linear in memory and still fast
+    // enough.
+    //
+    // to save some memory and since the weights are usually (negative)
+    // powers of 2, we choose the value type of the matrix to be @p{float}
+    // rather than @p{double}.
+    std::vector<std::map<types::global_dof_index, float> > weights;
+
+    // this is this mapping. there is one entry for each dof on the fine
+    // grid; if it is a parameter dof, then its value is the column in
+    // weights for that parameter dof, if it is any other dof, then its
+    // value is -1, indicating an error
+    std::vector<types::global_dof_index> weight_mapping;
+
+    internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
+                                           fine_grid, fine_component,
+                                           coarse_to_fine_grid_map,
+                                           weights, weight_mapping);
+
+    // now compute the requested representation
+    const types::global_dof_index n_global_parm_dofs
+      = std::count_if (weight_mapping.begin(), weight_mapping.end(),
+                       std::bind2nd (std::not_equal_to<types::global_dof_index> (), numbers::invalid_dof_index));
+
+    // first construct the inverse mapping of weight_mapping
+    std::vector<types::global_dof_index> inverse_weight_mapping (n_global_parm_dofs,
+        DoFHandler<dim,spacedim>::invalid_dof_index);
+    for (types::global_dof_index i=0; i<weight_mapping.size(); ++i)
+      {
+        const types::global_dof_index parameter_dof = weight_mapping[i];
+        // if this global dof is a parameter
+        if (parameter_dof != numbers::invalid_dof_index)
+          {
+            Assert (parameter_dof < n_global_parm_dofs, ExcInternalError());
+            Assert ((inverse_weight_mapping[parameter_dof] == DoFHandler<dim,spacedim>::invalid_dof_index),
+                    ExcInternalError());
+
+            inverse_weight_mapping[parameter_dof] = i;
+          };
+      };
+
+    // next copy over weights array and replace respective numbers
+    const types::global_dof_index n_rows = weight_mapping.size();
+
+    transfer_representation.clear ();
+    transfer_representation.resize (n_rows);
+
+    const types::global_dof_index n_coarse_dofs = coarse_grid.n_dofs();
+    for (types::global_dof_index i=0; i<n_coarse_dofs; ++i)
+      {
+        std::map<types::global_dof_index, float>::const_iterator j = weights[i].begin();
+        for (; j!=weights[i].end(); ++j)
+          {
+            const types::global_dof_index p = inverse_weight_mapping[j->first];
+            Assert (p<n_rows, ExcInternalError());
+
+            transfer_representation[p][i] = j->second;
+          };
+      };
+  }
+
+
+
+  template <int dim, int spacedim, template <int,int> class DH>
+  void
+  make_zero_boundary_constraints (const DH<dim, spacedim> &dof,
+                                  const types::boundary_id boundary_indicator,
+                                  ConstraintMatrix        &zero_boundary_constraints,
+                                  const ComponentMask     &component_mask)
+  {
+    Assert (component_mask.represents_n_components(dof.get_fe().n_components()),
+            ExcMessage ("The number of components in the mask has to be either "
+                        "zero or equal to the number of components in the finite "
+                        "element."));
+
+    const unsigned int n_components = DoFTools::n_components (dof);
+
+    Assert (component_mask.n_selected_components(n_components) > 0,
+            ComponentMask::ExcNoComponentSelected());
+
+    // a field to store the indices
+    std::vector<types::global_dof_index> face_dofs;
+    face_dofs.reserve (max_dofs_per_face(dof));
+
+    typename DH<dim,spacedim>::active_cell_iterator
+    cell = dof.begin_active(),
+    endc = dof.end();
+    for (; cell!=endc; ++cell)
+      if (!cell->is_artificial())
+        for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
+             ++face_no)
+          {
+            const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+
+            const typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
+
+            // if face is on the boundary and satisfies the correct
+            // boundary id property
+            if (face->at_boundary ()
+                &&
+                ((boundary_indicator == numbers::invalid_boundary_id)
+                 ||
+                 (face->boundary_indicator() == boundary_indicator)))
+              {
+                // get indices and physical location on this face
+                face_dofs.resize (fe.dofs_per_face);
+                face->get_dof_indices (face_dofs, cell->active_fe_index());
+
+                // enter those dofs into the list that match the component
+                // signature.
+                for (unsigned int i=0; i<face_dofs.size(); ++i)
+                  {
+                    // Find out if a dof has a contribution in this
+                    // component, and if so, add it to the list
+                    const ComponentMask &nonzero_component_array
+                      = cell->get_fe().get_nonzero_components (i);
+                    bool nonzero = false;
+                    for (unsigned int c=0; c<n_components; ++c)
+                      if (nonzero_component_array[c] && component_mask[c])
+                        {
+                          nonzero = true;
+                          break;
+                        }
+
+                    if (nonzero)
+                      zero_boundary_constraints.add_line (face_dofs[i]);
+                  }
+              }
+          }
+  }
+
+
+
+  template <int dim, int spacedim, template <int,int> class DH>
+  void
+  make_zero_boundary_constraints (const DH<dim, spacedim> &dof,
+                                  ConstraintMatrix        &zero_boundary_constraints,
+                                  const ComponentMask     &component_mask)
+  {
+    make_zero_boundary_constraints(dof, numbers::invalid_boundary_id,
+                                   zero_boundary_constraints, component_mask);
+  }
+
+
+} // end of namespace DoFTools
+
+
+
+// explicit instantiations
+
+#include "dof_tools_constraints.inst"
+
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/dofs/dof_tools_constraints.inst.in b/deal.II/source/dofs/dof_tools_constraints.inst.in
new file mode 100644 (file)
index 0000000..246f53a
--- /dev/null
@@ -0,0 +1,147 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2009 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+
+for (DH : DOFHANDLERS; deal_II_dimension : DIMENSIONS)
+{
+  template
+  void
+  DoFTools::make_hanging_node_constraints (const DH &dof_handler,
+                                           ConstraintMatrix &constraints);
+
+#if deal_II_dimension != 1
+  template
+  void
+  DoFTools::make_periodicity_constraints (const DH::face_iterator &,
+                                          const DH::face_iterator &,
+                                          dealii::ConstraintMatrix &,
+                                          const ComponentMask &,
+                                          bool, bool, bool);
+
+  template
+  void
+  DoFTools::make_periodicity_constraints(const DH &,
+                                         const types::boundary_id,
+                                         const types::boundary_id,
+                                         const int,
+                                         dealii::ConstraintMatrix &,
+                                         const ComponentMask &);
+
+  template
+  void
+  DoFTools::make_periodicity_constraints(const DH &,
+                                         const types::boundary_id,
+                                         const types::boundary_id,
+                                         const int,
+                                         dealii::Tensor<1,DH::space_dimension> &,
+                                         dealii::ConstraintMatrix &,
+                                         const ComponentMask &);
+
+  template
+  void
+  DoFTools::make_periodicity_constraints(const DH &,
+                                         const types::boundary_id,
+                                         const int,
+                                         dealii::ConstraintMatrix &,
+                                         const ComponentMask &);
+
+  template
+  void
+  DoFTools::make_periodicity_constraints(const DH &,
+                                         const types::boundary_id,
+                                         const int,
+                                         dealii::Tensor<1,DH::space_dimension> &,
+                                         dealii::ConstraintMatrix &,
+                                         const ComponentMask &);
+#endif
+}
+
+for (deal_II_dimension : DIMENSIONS)
+{
+#if deal_II_dimension != 1
+  template
+  void
+  DoFTools::make_hanging_node_constraints (const MGDoFHandler<deal_II_dimension> &dof_handler,
+                                           ConstraintMatrix &constraints);
+
+#endif
+
+#if deal_II_dimension < 3
+
+template
+void
+DoFTools::
+make_hanging_node_constraints (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_handler,
+                               ConstraintMatrix &constraints);
+#endif
+
+#if deal_II_dimension == 3
+template
+void
+DoFTools::
+make_hanging_node_constraints (const DoFHandler<1,3> &dof_handler,
+                               ConstraintMatrix &constraints);
+#endif
+
+template
+void
+DoFTools::make_zero_boundary_constraints
+(const DoFHandler<deal_II_dimension> &,
+ ConstraintMatrix                    &,
+ const ComponentMask             &);
+
+template
+void
+DoFTools::make_zero_boundary_constraints
+(const DoFHandler<deal_II_dimension> &,
+ const types::boundary_id          ,
+ ConstraintMatrix                    &,
+ const ComponentMask             &);
+
+template
+void
+DoFTools::make_zero_boundary_constraints
+(const hp::DoFHandler<deal_II_dimension> &,
+ ConstraintMatrix                        &,
+ const ComponentMask                 &);
+
+template
+void
+DoFTools::make_zero_boundary_constraints
+(const hp::DoFHandler<deal_II_dimension> &,
+ const types::boundary_id          ,
+ ConstraintMatrix                        &,
+ const ComponentMask                 &);
+
+template
+void
+DoFTools::compute_intergrid_constraints<deal_II_dimension> (
+  const DoFHandler<deal_II_dimension> &, const unsigned int,
+  const DoFHandler<deal_II_dimension> &, const unsigned int,
+  const InterGridMap<DoFHandler<deal_II_dimension> > &,
+  ConstraintMatrix&);
+
+template
+void
+DoFTools::compute_intergrid_transfer_representation<deal_II_dimension>
+(const DoFHandler<deal_II_dimension> &, const unsigned int,
+ const DoFHandler<deal_II_dimension> &, const unsigned int,
+ const InterGridMap<DoFHandler<deal_II_dimension> > &,
+ std::vector<std::map<types::global_dof_index, float> > &);
+
+}
diff --git a/deal.II/source/dofs/dof_tools_sparsity.cc b/deal.II/source/dofs/dof_tools_sparsity.cc
new file mode 100644 (file)
index 0000000..c48bf2f
--- /dev/null
@@ -0,0 +1,1179 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1999 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/base/multithread_info.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/table.h>
+#include <deal.II/base/template_constraints.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/sparsity_pattern.h>
+#include <deal.II/lac/compressed_sparsity_pattern.h>
+#include <deal.II/lac/compressed_set_sparsity_pattern.h>
+#include <deal.II/lac/compressed_simple_sparsity_pattern.h>
+#include <deal.II/lac/trilinos_sparsity_pattern.h>
+#include <deal.II/lac/block_sparsity_pattern.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/intergrid_map.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_tools.h>
+#include <deal.II/hp/fe_collection.h>
+#include <deal.II/hp/q_collection.h>
+#include <deal.II/hp/fe_values.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/numerics/vector_tools.h>
+
+#include <deal.II/multigrid/mg_dof_handler.h>
+
+#include <algorithm>
+#include <numeric>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+
+namespace DoFTools
+{
+
+  template <class DH, class SparsityPattern>
+  void
+  make_sparsity_pattern (const DH               &dof,
+                         SparsityPattern        &sparsity,
+                         const ConstraintMatrix &constraints,
+                         const bool              keep_constrained_dofs,
+                         const types::subdomain_id subdomain_id)
+  {
+    const types::global_dof_index n_dofs = dof.n_dofs();
+
+    Assert (sparsity.n_rows() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+    Assert (sparsity.n_cols() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+
+    // If we have a distributed::Triangulation only allow locally_owned
+    // subdomain. Not setting a subdomain is also okay, because we skip
+    // ghost cells in the loop below.
+    Assert (
+      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
+      ExcMessage ("For parallel::distributed::Triangulation objects and "
+                  "associated DoF handler objects, asking for any subdomain other "
+                  "than the locally owned one does not make sense."));
+
+    std::vector<types::global_dof_index> dofs_on_this_cell;
+    dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
+    typename DH::active_cell_iterator cell = dof.begin_active(),
+                                      endc = dof.end();
+
+    // In case we work with a distributed sparsity pattern of Trilinos
+    // type, we only have to do the work if the current cell is owned by
+    // the calling processor. Otherwise, just continue.
+    for (; cell!=endc; ++cell)
+      if (((subdomain_id == numbers::invalid_subdomain_id)
+           ||
+           (subdomain_id == cell->subdomain_id()))
+          &&
+          cell->is_locally_owned())
+        {
+          const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+          dofs_on_this_cell.resize (dofs_per_cell);
+          cell->get_dof_indices (dofs_on_this_cell);
+
+          // make sparsity pattern for this cell. if no constraints pattern
+          // was given, then the following call acts as if simply no
+          // constraints existed
+          constraints.add_entries_local_to_global (dofs_on_this_cell,
+                                                   sparsity,
+                                                   keep_constrained_dofs);
+        }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_sparsity_pattern (const DH                &dof,
+                         const Table<2,Coupling> &couplings,
+                         SparsityPattern         &sparsity,
+                         const ConstraintMatrix  &constraints,
+                         const bool               keep_constrained_dofs,
+                         const types::subdomain_id subdomain_id)
+  {
+    const types::global_dof_index n_dofs = dof.n_dofs();
+
+    Assert (sparsity.n_rows() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+    Assert (sparsity.n_cols() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+    Assert (couplings.n_rows() == dof.get_fe().n_components(),
+            ExcDimensionMismatch(couplings.n_rows(), dof.get_fe().n_components()));
+    Assert (couplings.n_cols() == dof.get_fe().n_components(),
+            ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().n_components()));
+
+    // If we have a distributed::Triangulation only allow locally_owned
+    // subdomain. Not setting a subdomain is also okay, because we skip
+    // ghost cells in the loop below.
+    Assert (
+      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
+      ExcMessage ("For parallel::distributed::Triangulation objects and "
+                  "associated DoF handler objects, asking for any subdomain other "
+                  "than the locally owned one does not make sense."));
+
+    const hp::FECollection<DH::dimension,DH::space_dimension> fe_collection (dof.get_fe());
+
+    // first, for each finite element, build a mask for each dof, not like
+    // the one given which represents components. make sure we do the right
+    // thing also with respect to non-primitive shape functions, which
+    // takes some additional thought
+    std::vector<Table<2,bool> > dof_mask(fe_collection.size());
+
+    // check whether the table of couplings contains only true arguments,
+    // i.e., we do not exclude any index. that is the easy case, since we
+    // don't have to set up the tables
+    bool need_dof_mask = false;
+    for (unsigned int i=0; i<couplings.n_rows(); ++i)
+      for (unsigned int j=0; j<couplings.n_cols(); ++j)
+        if (couplings(i,j) == none)
+          need_dof_mask = true;
+
+    if (need_dof_mask == true)
+      for (unsigned int f=0; f<fe_collection.size(); ++f)
+        {
+          const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
+
+          dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
+
+          for (unsigned int i=0; i<dofs_per_cell; ++i)
+            for (unsigned int j=0; j<dofs_per_cell; ++j)
+              if (fe_collection[f].is_primitive(i) &&
+                  fe_collection[f].is_primitive(j))
+                dof_mask[f](i,j)
+                  = (couplings(fe_collection[f].system_to_component_index(i).first,
+                               fe_collection[f].system_to_component_index(j).first) != none);
+              else
+                {
+                  const unsigned int first_nonzero_comp_i
+                    = fe_collection[f].get_nonzero_components(i).first_selected_component();
+                  const unsigned int first_nonzero_comp_j
+                    = fe_collection[f].get_nonzero_components(j).first_selected_component();
+                  Assert (first_nonzero_comp_i < fe_collection[f].n_components(),
+                          ExcInternalError());
+                  Assert (first_nonzero_comp_j < fe_collection[f].n_components(),
+                          ExcInternalError());
+
+                  dof_mask[f](i,j)
+                    = (couplings(first_nonzero_comp_i,first_nonzero_comp_j) != none);
+                }
+        }
+
+
+    std::vector<types::global_dof_index> dofs_on_this_cell(fe_collection.max_dofs_per_cell());
+    typename DH::active_cell_iterator cell = dof.begin_active(),
+                                      endc = dof.end();
+
+    // In case we work with a distributed sparsity pattern of Trilinos
+    // type, we only have to do the work if the current cell is owned by
+    // the calling processor. Otherwise, just continue.
+    for (; cell!=endc; ++cell)
+      if (((subdomain_id == numbers::invalid_subdomain_id)
+           ||
+           (subdomain_id == cell->subdomain_id()))
+          &&
+          cell->is_locally_owned())
+        {
+          const unsigned int fe_index = cell->active_fe_index();
+          const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
+
+          dofs_on_this_cell.resize (dofs_per_cell);
+          cell->get_dof_indices (dofs_on_this_cell);
+
+
+          // make sparsity pattern for this cell. if no constraints pattern
+          // was given, then the following call acts as if simply no
+          // constraints existed
+          constraints.add_entries_local_to_global (dofs_on_this_cell,
+                                                   sparsity,
+                                                   keep_constrained_dofs,
+                                                   dof_mask[fe_index]);
+        }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_sparsity_pattern (
+    const DH        &dof_row,
+    const DH        &dof_col,
+    SparsityPattern &sparsity)
+  {
+    const types::global_dof_index n_dofs_row = dof_row.n_dofs();
+    const types::global_dof_index n_dofs_col = dof_col.n_dofs();
+
+    Assert (sparsity.n_rows() == n_dofs_row,
+            ExcDimensionMismatch (sparsity.n_rows(), n_dofs_row));
+    Assert (sparsity.n_cols() == n_dofs_col,
+            ExcDimensionMismatch (sparsity.n_cols(), n_dofs_col));
+
+//TODO: Looks like wasteful memory management here
+
+    const std::list<std::pair<typename DH::cell_iterator,
+          typename DH::cell_iterator> >
+          cell_list
+          = GridTools::get_finest_common_cells (dof_row, dof_col);
+
+
+    typename std::list<std::pair<typename DH::cell_iterator,
+             typename DH::cell_iterator> >::const_iterator
+             cell_iter = cell_list.begin();
+
+    for (; cell_iter!=cell_list.end(); ++cell_iter)
+      {
+        const typename DH::cell_iterator cell_row = cell_iter->first;
+        const typename DH::cell_iterator cell_col = cell_iter->second;
+
+        if (!cell_row->has_children() && !cell_col->has_children())
+          {
+            const unsigned int dofs_per_cell_row =
+              cell_row->get_fe().dofs_per_cell;
+            const unsigned int dofs_per_cell_col =
+              cell_col->get_fe().dofs_per_cell;
+            std::vector<types::global_dof_index>
+            local_dof_indices_row(dofs_per_cell_row);
+            std::vector<types::global_dof_index>
+            local_dof_indices_col(dofs_per_cell_col);
+            cell_row->get_dof_indices (local_dof_indices_row);
+            cell_col->get_dof_indices (local_dof_indices_col);
+            for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+              sparsity.add_entries (local_dof_indices_row[i],
+                                    local_dof_indices_col.begin(),
+                                    local_dof_indices_col.end());
+          }
+        else if (cell_row->has_children())
+          {
+            const std::vector<typename DH::active_cell_iterator >
+            child_cells = GridTools::get_active_child_cells<DH> (cell_row);
+            for (unsigned int i=0; i<child_cells.size(); i++)
+              {
+                const typename DH::cell_iterator
+                cell_row_child = child_cells[i];
+                const unsigned int dofs_per_cell_row =
+                  cell_row_child->get_fe().dofs_per_cell;
+                const unsigned int dofs_per_cell_col =
+                  cell_col->get_fe().dofs_per_cell;
+                std::vector<types::global_dof_index>
+                local_dof_indices_row(dofs_per_cell_row);
+                std::vector<types::global_dof_index>
+                local_dof_indices_col(dofs_per_cell_col);
+                cell_row_child->get_dof_indices (local_dof_indices_row);
+                cell_col->get_dof_indices (local_dof_indices_col);
+                for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+                  sparsity.add_entries (local_dof_indices_row[i],
+                                        local_dof_indices_col.begin(),
+                                        local_dof_indices_col.end());
+              }
+          }
+        else
+          {
+            std::vector<typename DH::active_cell_iterator>
+            child_cells = GridTools::get_active_child_cells<DH> (cell_col);
+            for (unsigned int i=0; i<child_cells.size(); i++)
+              {
+                const typename DH::active_cell_iterator
+                cell_col_child = child_cells[i];
+                const unsigned int dofs_per_cell_row =
+                  cell_row->get_fe().dofs_per_cell;
+                const unsigned int dofs_per_cell_col =
+                  cell_col_child->get_fe().dofs_per_cell;
+                std::vector<types::global_dof_index>
+                local_dof_indices_row(dofs_per_cell_row);
+                std::vector<types::global_dof_index>
+                local_dof_indices_col(dofs_per_cell_col);
+                cell_row->get_dof_indices (local_dof_indices_row);
+                cell_col_child->get_dof_indices (local_dof_indices_col);
+                for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+                  sparsity.add_entries (local_dof_indices_row[i],
+                                        local_dof_indices_col.begin(),
+                                        local_dof_indices_col.end());
+              }
+          }
+      }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_boundary_sparsity_pattern (
+    const DH                        &dof,
+    const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
+    SparsityPattern                 &sparsity)
+  {
+    if (DH::dimension == 1)
+      {
+        // there are only 2 boundary indicators in 1d, so it is no
+        // performance problem to call the other function
+        typename DH::FunctionMap boundary_indicators;
+        boundary_indicators[0] = 0;
+        boundary_indicators[1] = 0;
+        make_boundary_sparsity_pattern<DH, SparsityPattern> (dof,
+                                                             boundary_indicators,
+                                                             dof_to_boundary_mapping,
+                                                             sparsity);
+        return;
+      }
+
+    const types::global_dof_index n_dofs = dof.n_dofs();
+
+    AssertDimension (dof_to_boundary_mapping.size(), n_dofs);
+    AssertDimension (sparsity.n_rows(), dof.n_boundary_dofs());
+    AssertDimension (sparsity.n_cols(), dof.n_boundary_dofs());
+#ifdef DEBUG
+    if (sparsity.n_rows() != 0)
+      {
+        types::global_dof_index max_element = 0;
+        for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
+             i!=dof_to_boundary_mapping.end(); ++i)
+          if ((*i != DH::invalid_dof_index) &&
+              (*i > max_element))
+            max_element = *i;
+        AssertDimension (max_element, sparsity.n_rows()-1);
+      };
+#endif
+
+    std::vector<types::global_dof_index> dofs_on_this_face;
+    dofs_on_this_face.reserve (max_dofs_per_face(dof));
+
+    // loop over all faces to check whether they are at a boundary. note
+    // that we need not take special care of single lines (using
+    // @p{cell->has_boundary_lines}), since we do not support boundaries of
+    // dimension dim-2, and so every boundary line is also part of a
+    // boundary face.
+    typename DH::active_cell_iterator cell = dof.begin_active(),
+                                      endc = dof.end();
+    for (; cell!=endc; ++cell)
+      for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+        if (cell->at_boundary(f))
+          {
+            const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+            dofs_on_this_face.resize (dofs_per_face);
+            cell->face(f)->get_dof_indices (dofs_on_this_face,
+                                            cell->active_fe_index());
+
+            // make sparsity pattern for this cell
+            for (unsigned int i=0; i<dofs_per_face; ++i)
+              for (unsigned int j=0; j<dofs_per_face; ++j)
+                sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
+                              dof_to_boundary_mapping[dofs_on_this_face[j]]);
+          }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void make_boundary_sparsity_pattern (
+    const DH                                        &dof,
+    const typename FunctionMap<DH::space_dimension>::type &boundary_indicators,
+    const std::vector<types::global_dof_index>                 &dof_to_boundary_mapping,
+    SparsityPattern                                 &sparsity)
+  {
+    if (DH::dimension == 1)
+      {
+        // first check left, then right boundary point
+        for (unsigned int direction=0; direction<2; ++direction)
+          {
+            // if this boundary is not requested, then go on with next one
+            if (boundary_indicators.find(direction) ==
+                boundary_indicators.end())
+              continue;
+
+            // find active cell at that boundary: first go to left/right,
+            // then to children
+            typename DH::level_cell_iterator cell = dof.begin(0);
+            while (!cell->at_boundary(direction))
+              cell = cell->neighbor(direction);
+            while (!cell->active())
+              cell = cell->child(direction);
+
+            const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
+            std::vector<types::global_dof_index> boundary_dof_boundary_indices (dofs_per_vertex);
+
+            // next get boundary mapped dof indices of boundary dofs
+            for (unsigned int i=0; i<dofs_per_vertex; ++i)
+              boundary_dof_boundary_indices[i]
+                = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
+
+            for (unsigned int i=0; i<dofs_per_vertex; ++i)
+              sparsity.add_entries (boundary_dof_boundary_indices[i],
+                                    boundary_dof_boundary_indices.begin(),
+                                    boundary_dof_boundary_indices.end());
+          };
+        return;
+      }
+
+    const types::global_dof_index n_dofs = dof.n_dofs();
+
+    AssertDimension (dof_to_boundary_mapping.size(), n_dofs);
+    Assert (boundary_indicators.find(numbers::internal_face_boundary_id) == boundary_indicators.end(),
+            typename DH::ExcInvalidBoundaryIndicator());
+    Assert (sparsity.n_rows() == dof.n_boundary_dofs (boundary_indicators),
+            ExcDimensionMismatch (sparsity.n_rows(), dof.n_boundary_dofs (boundary_indicators)));
+    Assert (sparsity.n_cols() == dof.n_boundary_dofs (boundary_indicators),
+            ExcDimensionMismatch (sparsity.n_cols(), dof.n_boundary_dofs (boundary_indicators)));
+#ifdef DEBUG
+    if (sparsity.n_rows() != 0)
+      {
+        types::global_dof_index max_element = 0;
+        for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
+             i!=dof_to_boundary_mapping.end(); ++i)
+          if ((*i != DH::invalid_dof_index) &&
+              (*i > max_element))
+            max_element = *i;
+        AssertDimension (max_element, sparsity.n_rows()-1);
+      };
+#endif
+
+    std::vector<types::global_dof_index> dofs_on_this_face;
+    dofs_on_this_face.reserve (max_dofs_per_face(dof));
+    typename DH::active_cell_iterator cell = dof.begin_active(),
+                                      endc = dof.end();
+    for (; cell!=endc; ++cell)
+      for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+        if (boundary_indicators.find(cell->face(f)->boundary_indicator()) !=
+            boundary_indicators.end())
+          {
+            const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+            dofs_on_this_face.resize (dofs_per_face);
+            cell->face(f)->get_dof_indices (dofs_on_this_face,
+                                            cell->active_fe_index());
+
+            // make sparsity pattern for this cell
+            for (unsigned int i=0; i<dofs_per_face; ++i)
+              for (unsigned int j=0; j<dofs_per_face; ++j)
+                sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
+                              dof_to_boundary_mapping[dofs_on_this_face[j]]);
+          }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_flux_sparsity_pattern (const DH                  &dof,
+                              SparsityPattern           &sparsity,
+                              const ConstraintMatrix    &constraints,
+                              const bool                keep_constrained_dofs,
+                              const types::subdomain_id subdomain_id)
+
+  // TODO: QA: reduce the indentation level of this method..., Maier 2012
+
+  {
+    const types::global_dof_index n_dofs = dof.n_dofs();
+
+    AssertDimension (sparsity.n_rows(), n_dofs);
+    AssertDimension (sparsity.n_cols(), n_dofs);
+
+    // If we have a distributed::Triangulation only allow locally_owned
+    // subdomain. Not setting a subdomain is also okay, because we skip
+    // ghost cells in the loop below.
+    Assert (
+      (dof.get_tria().locally_owned_subdomain() == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == numbers::invalid_subdomain_id)
+      ||
+      (subdomain_id == dof.get_tria().locally_owned_subdomain()),
+      ExcMessage ("For parallel::distributed::Triangulation objects and "
+                  "associated DoF handler objects, asking for any subdomain other "
+                  "than the locally owned one does not make sense."));
+
+    std::vector<types::global_dof_index> dofs_on_this_cell;
+    std::vector<types::global_dof_index> dofs_on_other_cell;
+    dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
+    dofs_on_other_cell.reserve (max_dofs_per_cell(dof));
+    typename DH::active_cell_iterator cell = dof.begin_active(),
+                                      endc = dof.end();
+
+    // TODO: in an old implementation, we used user flags before to tag
+    // faces that were already touched. this way, we could reduce the work
+    // a little bit. now, we instead add only data from one side. this
+    // should be OK, but we need to actually verify it.
+
+    // In case we work with a distributed sparsity pattern of Trilinos
+    // type, we only have to do the work if the current cell is owned by
+    // the calling processor. Otherwise, just continue.
+    for (; cell!=endc; ++cell)
+      if (((subdomain_id == numbers::invalid_subdomain_id)
+           ||
+           (subdomain_id == cell->subdomain_id()))
+          &&
+          cell->is_locally_owned())
+        {
+          const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
+          dofs_on_this_cell.resize (n_dofs_on_this_cell);
+          cell->get_dof_indices (dofs_on_this_cell);
+
+          // make sparsity pattern for this cell. if no constraints pattern
+          // was given, then the following call acts as if simply no
+          // constraints existed
+          constraints.add_entries_local_to_global (dofs_on_this_cell,
+                                                   sparsity,
+                                                   keep_constrained_dofs);
+
+          for (unsigned int face = 0;
+               face < GeometryInfo<DH::dimension>::faces_per_cell;
+               ++face)
+            {
+              typename DH::face_iterator cell_face = cell->face(face);
+              if (! cell->at_boundary(face) )
+                {
+                  typename DH::level_cell_iterator neighbor = cell->neighbor(face);
+
+                  // in 1d, we do not need to worry whether the neighbor
+                  // might have children and then loop over those children.
+                  // rather, we may as well go straight to to cell behind
+                  // this particular cell's most terminal child
+                  if (DH::dimension==1)
+                    while (neighbor->has_children())
+                      neighbor = neighbor->child(face==0 ? 1 : 0);
+
+                  if (neighbor->has_children())
+                    {
+                      for (unsigned int sub_nr = 0;
+                           sub_nr != cell_face->number_of_children();
+                           ++sub_nr)
+                        {
+                          const typename DH::level_cell_iterator
+                          sub_neighbor
+                            = cell->neighbor_child_on_subface (face, sub_nr);
+
+                          const unsigned int n_dofs_on_neighbor
+                            = sub_neighbor->get_fe().dofs_per_cell;
+                          dofs_on_other_cell.resize (n_dofs_on_neighbor);
+                          sub_neighbor->get_dof_indices (dofs_on_other_cell);
+
+                          constraints.add_entries_local_to_global
+                          (dofs_on_this_cell, dofs_on_other_cell,
+                           sparsity, keep_constrained_dofs);
+                          constraints.add_entries_local_to_global
+                          (dofs_on_other_cell, dofs_on_this_cell,
+                           sparsity, keep_constrained_dofs);
+                        }
+                    }
+                  else
+                    {
+                      // Refinement edges are taken care of by coarser
+                      // cells
+
+                      // TODO: in the distributed case, we miss out the
+                      // constraints when the neighbor cell is coarser, but
+                      // only the current cell is owned locally!
+                      if (cell->neighbor_is_coarser(face))
+                        continue;
+
+                      const unsigned int n_dofs_on_neighbor
+                        = neighbor->get_fe().dofs_per_cell;
+                      dofs_on_other_cell.resize (n_dofs_on_neighbor);
+
+                      neighbor->get_dof_indices (dofs_on_other_cell);
+
+                      constraints.add_entries_local_to_global
+                      (dofs_on_this_cell, dofs_on_other_cell,
+                       sparsity, keep_constrained_dofs);
+
+                      // only need to add these in case the neighbor cell
+                      // is not locally owned - otherwise, we touch each
+                      // face twice and hence put the indices the other way
+                      // around
+                      if (!cell->neighbor(face)->active()
+                          ||
+                          (cell->neighbor(face)->subdomain_id() !=
+                           cell->subdomain_id()))
+                        constraints.add_entries_local_to_global
+                        (dofs_on_other_cell, dofs_on_this_cell,
+                         sparsity, keep_constrained_dofs);
+                    }
+                }
+            }
+        }
+  }
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_flux_sparsity_pattern (const DH        &dof,
+                              SparsityPattern &sparsity)
+  {
+    ConstraintMatrix constraints;
+    make_flux_sparsity_pattern (dof, sparsity, constraints);
+  }
+
+  template <int dim, int spacedim>
+  Table<2,Coupling>
+  dof_couplings_from_component_couplings (const FiniteElement<dim,spacedim> &fe,
+                                          const Table<2,Coupling> &component_couplings)
+  {
+    Assert(component_couplings.n_rows() == fe.n_components(),
+           ExcDimensionMismatch(component_couplings.n_rows(),
+                                fe.n_components()));
+    Assert(component_couplings.n_cols() == fe.n_components(),
+           ExcDimensionMismatch(component_couplings.n_cols(),
+                                fe.n_components()));
+
+    const unsigned int n_dofs = fe.dofs_per_cell;
+
+    Table<2,Coupling> dof_couplings (n_dofs, n_dofs);
+
+    for (unsigned int i=0; i<n_dofs; ++i)
+      {
+        const unsigned int ii
+          = (fe.is_primitive(i) ?
+             fe.system_to_component_index(i).first
+             :
+             fe.get_nonzero_components(i).first_selected_component()
+            );
+        Assert (ii < fe.n_components(), ExcInternalError());
+
+        for (unsigned int j=0; j<n_dofs; ++j)
+          {
+            const unsigned int jj
+              = (fe.is_primitive(j) ?
+                 fe.system_to_component_index(j).first
+                 :
+                 fe.get_nonzero_components(j).first_selected_component()
+                );
+            Assert (jj < fe.n_components(), ExcInternalError());
+
+            dof_couplings(i,j) = component_couplings(ii,jj);
+          }
+      }
+    return dof_couplings;
+  }
+
+
+
+  template <int dim, int spacedim>
+  std::vector<Table<2,Coupling> >
+  dof_couplings_from_component_couplings
+  (const hp::FECollection<dim,spacedim> &fe,
+   const Table<2,Coupling> &component_couplings)
+  {
+    std::vector<Table<2,Coupling> > return_value (fe.size());
+    for (unsigned int i=0; i<fe.size(); ++i)
+      return_value[i]
+        = dof_couplings_from_component_couplings(fe[i], component_couplings);
+
+    return return_value;
+  }
+
+
+
+  namespace internal
+  {
+    namespace
+    {
+
+      // implementation of the same function in namespace DoFTools for
+      // non-hp DoFHandlers
+      template <class DH, class SparsityPattern>
+      void
+      make_flux_sparsity_pattern (const DH                &dof,
+                                  SparsityPattern         &sparsity,
+                                  const Table<2,Coupling> &int_mask,
+                                  const Table<2,Coupling> &flux_mask)
+      {
+        const FiniteElement<DH::dimension,DH::space_dimension> &fe = dof.get_fe();
+
+        std::vector<types::global_dof_index> dofs_on_this_cell(fe.dofs_per_cell);
+        std::vector<types::global_dof_index> dofs_on_other_cell(fe.dofs_per_cell);
+
+        const Table<2,Coupling>
+        int_dof_mask  = dof_couplings_from_component_couplings(fe, int_mask),
+        flux_dof_mask = dof_couplings_from_component_couplings(fe, flux_mask);
+
+        Table<2,bool> support_on_face(fe.dofs_per_cell,
+                                      GeometryInfo<DH::dimension>::faces_per_cell);
+        for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+          for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+            support_on_face(i,f) = fe.has_support_on_face(i,f);
+
+        typename DH::active_cell_iterator cell = dof.begin_active(),
+                                          endc = dof.end();
+        for (; cell!=endc; ++cell)
+          if (cell->is_locally_owned())
+            {
+              cell->get_dof_indices (dofs_on_this_cell);
+              // make sparsity pattern for this cell
+              for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+                for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+                  if (int_dof_mask(i,j) != none)
+                    sparsity.add (dofs_on_this_cell[i],
+                                  dofs_on_this_cell[j]);
+
+              // Loop over all interior neighbors
+              for (unsigned int face = 0;
+                   face < GeometryInfo<DH::dimension>::faces_per_cell;
+                   ++face)
+                {
+                  const typename DH::face_iterator
+                  cell_face = cell->face(face);
+                  if (cell_face->user_flag_set ())
+                    continue;
+
+                  if (cell->at_boundary (face) )
+                    {
+                      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+                        {
+                          const bool i_non_zero_i = support_on_face (i, face);
+                          for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+                            {
+                              const bool j_non_zero_i = support_on_face (j, face);
+
+                              if ((flux_dof_mask(i,j) == always)
+                                  ||
+                                  (flux_dof_mask(i,j) == nonzero
+                                   &&
+                                   i_non_zero_i
+                                   &&
+                                   j_non_zero_i))
+                                sparsity.add (dofs_on_this_cell[i],
+                                              dofs_on_this_cell[j]);
+                            }
+                        }
+                    }
+                  else
+                    {
+                      typename DH::level_cell_iterator
+                      neighbor = cell->neighbor(face);
+                      // Refinement edges are taken care of by coarser
+                      // cells
+                      if (cell->neighbor_is_coarser(face))
+                        continue;
+
+                      typename DH::face_iterator cell_face = cell->face(face);
+                      const unsigned int
+                      neighbor_face = cell->neighbor_of_neighbor(face);
+
+                      if (cell_face->has_children())
+                        {
+                          for (unsigned int sub_nr = 0;
+                               sub_nr != cell_face->n_children();
+                               ++sub_nr)
+                            {
+                              const typename DH::level_cell_iterator
+                              sub_neighbor
+                                = cell->neighbor_child_on_subface (face, sub_nr);
+
+                              sub_neighbor->get_dof_indices (dofs_on_other_cell);
+                              for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+                                {
+                                  const bool i_non_zero_i = support_on_face (i, face);
+                                  const bool i_non_zero_e = support_on_face (i, neighbor_face);
+                                  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+                                    {
+                                      const bool j_non_zero_i = support_on_face (j, face);
+                                      const bool j_non_zero_e = support_on_face (j, neighbor_face);
+
+                                      if (flux_dof_mask(i,j) == always)
+                                        {
+                                          sparsity.add (dofs_on_this_cell[i],
+                                                        dofs_on_other_cell[j]);
+                                          sparsity.add (dofs_on_other_cell[i],
+                                                        dofs_on_this_cell[j]);
+                                          sparsity.add (dofs_on_this_cell[i],
+                                                        dofs_on_this_cell[j]);
+                                          sparsity.add (dofs_on_other_cell[i],
+                                                        dofs_on_other_cell[j]);
+                                        }
+                                      else if (flux_dof_mask(i,j) == nonzero)
+                                        {
+                                          if (i_non_zero_i && j_non_zero_e)
+                                            sparsity.add (dofs_on_this_cell[i],
+                                                          dofs_on_other_cell[j]);
+                                          if (i_non_zero_e && j_non_zero_i)
+                                            sparsity.add (dofs_on_other_cell[i],
+                                                          dofs_on_this_cell[j]);
+                                          if (i_non_zero_i && j_non_zero_i)
+                                            sparsity.add (dofs_on_this_cell[i],
+                                                          dofs_on_this_cell[j]);
+                                          if (i_non_zero_e && j_non_zero_e)
+                                            sparsity.add (dofs_on_other_cell[i],
+                                                          dofs_on_other_cell[j]);
+                                        }
+
+                                      if (flux_dof_mask(j,i) == always)
+                                        {
+                                          sparsity.add (dofs_on_this_cell[j],
+                                                        dofs_on_other_cell[i]);
+                                          sparsity.add (dofs_on_other_cell[j],
+                                                        dofs_on_this_cell[i]);
+                                          sparsity.add (dofs_on_this_cell[j],
+                                                        dofs_on_this_cell[i]);
+                                          sparsity.add (dofs_on_other_cell[j],
+                                                        dofs_on_other_cell[i]);
+                                        }
+                                      else if (flux_dof_mask(j,i) == nonzero)
+                                        {
+                                          if (j_non_zero_i && i_non_zero_e)
+                                            sparsity.add (dofs_on_this_cell[j],
+                                                          dofs_on_other_cell[i]);
+                                          if (j_non_zero_e && i_non_zero_i)
+                                            sparsity.add (dofs_on_other_cell[j],
+                                                          dofs_on_this_cell[i]);
+                                          if (j_non_zero_i && i_non_zero_i)
+                                            sparsity.add (dofs_on_this_cell[j],
+                                                          dofs_on_this_cell[i]);
+                                          if (j_non_zero_e && i_non_zero_e)
+                                            sparsity.add (dofs_on_other_cell[j],
+                                                          dofs_on_other_cell[i]);
+                                        }
+                                    }
+                                }
+                              sub_neighbor->face(neighbor_face)->set_user_flag ();
+                            }
+                        }
+                      else
+                        {
+                          neighbor->get_dof_indices (dofs_on_other_cell);
+                          for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+                            {
+                              const bool i_non_zero_i = support_on_face (i, face);
+                              const bool i_non_zero_e = support_on_face (i, neighbor_face);
+                              for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+                                {
+                                  const bool j_non_zero_i = support_on_face (j, face);
+                                  const bool j_non_zero_e = support_on_face (j, neighbor_face);
+                                  if (flux_dof_mask(i,j) == always)
+                                    {
+                                      sparsity.add (dofs_on_this_cell[i],
+                                                    dofs_on_other_cell[j]);
+                                      sparsity.add (dofs_on_other_cell[i],
+                                                    dofs_on_this_cell[j]);
+                                      sparsity.add (dofs_on_this_cell[i],
+                                                    dofs_on_this_cell[j]);
+                                      sparsity.add (dofs_on_other_cell[i],
+                                                    dofs_on_other_cell[j]);
+                                    }
+                                  if (flux_dof_mask(i,j) == nonzero)
+                                    {
+                                      if (i_non_zero_i && j_non_zero_e)
+                                        sparsity.add (dofs_on_this_cell[i],
+                                                      dofs_on_other_cell[j]);
+                                      if (i_non_zero_e && j_non_zero_i)
+                                        sparsity.add (dofs_on_other_cell[i],
+                                                      dofs_on_this_cell[j]);
+                                      if (i_non_zero_i && j_non_zero_i)
+                                        sparsity.add (dofs_on_this_cell[i],
+                                                      dofs_on_this_cell[j]);
+                                      if (i_non_zero_e && j_non_zero_e)
+                                        sparsity.add (dofs_on_other_cell[i],
+                                                      dofs_on_other_cell[j]);
+                                    }
+
+                                  if (flux_dof_mask(j,i) == always)
+                                    {
+                                      sparsity.add (dofs_on_this_cell[j],
+                                                    dofs_on_other_cell[i]);
+                                      sparsity.add (dofs_on_other_cell[j],
+                                                    dofs_on_this_cell[i]);
+                                      sparsity.add (dofs_on_this_cell[j],
+                                                    dofs_on_this_cell[i]);
+                                      sparsity.add (dofs_on_other_cell[j],
+                                                    dofs_on_other_cell[i]);
+                                    }
+                                  if (flux_dof_mask(j,i) == nonzero)
+                                    {
+                                      if (j_non_zero_i && i_non_zero_e)
+                                        sparsity.add (dofs_on_this_cell[j],
+                                                      dofs_on_other_cell[i]);
+                                      if (j_non_zero_e && i_non_zero_i)
+                                        sparsity.add (dofs_on_other_cell[j],
+                                                      dofs_on_this_cell[i]);
+                                      if (j_non_zero_i && i_non_zero_i)
+                                        sparsity.add (dofs_on_this_cell[j],
+                                                      dofs_on_this_cell[i]);
+                                      if (j_non_zero_e && i_non_zero_e)
+                                        sparsity.add (dofs_on_other_cell[j],
+                                                      dofs_on_other_cell[i]);
+                                    }
+                                }
+                            }
+                          neighbor->face(neighbor_face)->set_user_flag ();
+                        }
+                    }
+                }
+            }
+      }
+
+
+      // implementation of the same function in namespace DoFTools for
+      // non-hp DoFHandlers
+      template <int dim, int spacedim, class SparsityPattern>
+      void
+      make_flux_sparsity_pattern (const dealii::hp::DoFHandler<dim,spacedim> &dof,
+                                  SparsityPattern                           &sparsity,
+                                  const Table<2,Coupling> &int_mask,
+                                  const Table<2,Coupling> &flux_mask)
+      {
+        // while the implementation above is quite optimized and caches a
+        // lot of data (see e.g. the int/flux_dof_mask tables), this is no
+        // longer practical for the hp version since we would have to have
+        // it for all combinations of elements in the hp::FECollection.
+        // consequently, the implementation here is simpler and probably
+        // less efficient but at least readable...
+
+        const dealii::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
+
+        std::vector<types::global_dof_index> dofs_on_this_cell(DoFTools::max_dofs_per_cell(dof));
+        std::vector<types::global_dof_index> dofs_on_other_cell(DoFTools::max_dofs_per_cell(dof));
+
+        const std::vector<Table<2,Coupling> >
+        int_dof_mask
+          = dof_couplings_from_component_couplings(fe, int_mask);
+
+        typename dealii::hp::DoFHandler<dim,spacedim>::active_cell_iterator
+        cell = dof.begin_active(),
+        endc = dof.end();
+        for (; cell!=endc; ++cell)
+          {
+            dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
+            cell->get_dof_indices (dofs_on_this_cell);
+
+            // make sparsity pattern for this cell
+            for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+              for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
+                if (int_dof_mask[cell->active_fe_index()](i,j) != none)
+                  sparsity.add (dofs_on_this_cell[i],
+                                dofs_on_this_cell[j]);
+
+            // Loop over all interior neighbors
+            for (unsigned int face = 0;
+                 face < GeometryInfo<dim>::faces_per_cell;
+                 ++face)
+              {
+                const typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
+                cell_face = cell->face(face);
+                if (cell_face->user_flag_set ())
+                  continue;
+
+                if (cell->at_boundary (face) )
+                  {
+                    for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+                      for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
+                        if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                       cell->get_fe().system_to_component_index(j).first)
+                             == always)
+                            ||
+                            (flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                       cell->get_fe().system_to_component_index(j).first)
+                             == nonzero))
+                          sparsity.add (dofs_on_this_cell[i],
+                                        dofs_on_this_cell[j]);
+                  }
+                else
+                  {
+                    typename dealii::hp::DoFHandler<dim,spacedim>::level_cell_iterator
+                    neighbor = cell->neighbor(face);
+
+                    // Refinement edges are taken care of by coarser cells
+                    if (cell->neighbor_is_coarser(face))
+                      continue;
+
+                    typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
+                    cell_face = cell->face(face);
+                    const unsigned int
+                    neighbor_face = cell->neighbor_of_neighbor(face);
+
+                    if (cell_face->has_children())
+                      {
+                        for (unsigned int sub_nr = 0;
+                             sub_nr != cell_face->n_children();
+                             ++sub_nr)
+                          {
+                            const typename dealii::hp::DoFHandler<dim,spacedim>::level_cell_iterator
+                            sub_neighbor
+                              = cell->neighbor_child_on_subface (face, sub_nr);
+
+                            dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
+                            sub_neighbor->get_dof_indices (dofs_on_other_cell);
+                            for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+                              {
+                                for (unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
+                                     ++j)
+                                  {
+                                    if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                                   sub_neighbor->get_fe().system_to_component_index(j).first)
+                                         == always)
+                                        ||
+                                        (flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                                   sub_neighbor->get_fe().system_to_component_index(j).first)
+                                         == nonzero))
+                                      {
+                                        sparsity.add (dofs_on_this_cell[i],
+                                                      dofs_on_other_cell[j]);
+                                        sparsity.add (dofs_on_other_cell[i],
+                                                      dofs_on_this_cell[j]);
+                                        sparsity.add (dofs_on_this_cell[i],
+                                                      dofs_on_this_cell[j]);
+                                        sparsity.add (dofs_on_other_cell[i],
+                                                      dofs_on_other_cell[j]);
+                                      }
+
+                                    if ((flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
+                                                   cell->get_fe().system_to_component_index(i).first)
+                                         == always)
+                                        ||
+                                        (flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
+                                                   cell->get_fe().system_to_component_index(i).first)
+                                         == nonzero))
+                                      {
+                                        sparsity.add (dofs_on_this_cell[j],
+                                                      dofs_on_other_cell[i]);
+                                        sparsity.add (dofs_on_other_cell[j],
+                                                      dofs_on_this_cell[i]);
+                                        sparsity.add (dofs_on_this_cell[j],
+                                                      dofs_on_this_cell[i]);
+                                        sparsity.add (dofs_on_other_cell[j],
+                                                      dofs_on_other_cell[i]);
+                                      }
+                                  }
+                              }
+                            sub_neighbor->face(neighbor_face)->set_user_flag ();
+                          }
+                      }
+                    else
+                      {
+                        dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
+                        neighbor->get_dof_indices (dofs_on_other_cell);
+                        for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+                          {
+                            for (unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
+                              {
+                                if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                               neighbor->get_fe().system_to_component_index(j).first)
+                                     == always)
+                                    ||
+                                    (flux_mask(cell->get_fe().system_to_component_index(i).first,
+                                               neighbor->get_fe().system_to_component_index(j).first)
+                                     == nonzero))
+                                  {
+                                    sparsity.add (dofs_on_this_cell[i],
+                                                  dofs_on_other_cell[j]);
+                                    sparsity.add (dofs_on_other_cell[i],
+                                                  dofs_on_this_cell[j]);
+                                    sparsity.add (dofs_on_this_cell[i],
+                                                  dofs_on_this_cell[j]);
+                                    sparsity.add (dofs_on_other_cell[i],
+                                                  dofs_on_other_cell[j]);
+                                  }
+
+                                if ((flux_mask(neighbor->get_fe().system_to_component_index(j).first,
+                                               cell->get_fe().system_to_component_index(i).first)
+                                     == always)
+                                    ||
+                                    (flux_mask(neighbor->get_fe().system_to_component_index(j).first,
+                                               cell->get_fe().system_to_component_index(i).first)
+                                     == nonzero))
+                                  {
+                                    sparsity.add (dofs_on_this_cell[j],
+                                                  dofs_on_other_cell[i]);
+                                    sparsity.add (dofs_on_other_cell[j],
+                                                  dofs_on_this_cell[i]);
+                                    sparsity.add (dofs_on_this_cell[j],
+                                                  dofs_on_this_cell[i]);
+                                    sparsity.add (dofs_on_other_cell[j],
+                                                  dofs_on_other_cell[i]);
+                                  }
+                              }
+                          }
+                        neighbor->face(neighbor_face)->set_user_flag ();
+                      }
+                  }
+              }
+          }
+      }
+    }
+
+  }
+
+
+
+
+  template <class DH, class SparsityPattern>
+  void
+  make_flux_sparsity_pattern (const DH                &dof,
+                              SparsityPattern         &sparsity,
+                              const Table<2,Coupling> &int_mask,
+                              const Table<2,Coupling> &flux_mask)
+  {
+    // do the error checking and frame code here, and then pass on to more
+    // specialized functions in the internal namespace
+    const types::global_dof_index n_dofs = dof.n_dofs();
+    const unsigned int n_comp = dof.get_fe().n_components();
+
+    Assert (sparsity.n_rows() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+    Assert (sparsity.n_cols() == n_dofs,
+            ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+    Assert (int_mask.n_rows() == n_comp,
+            ExcDimensionMismatch (int_mask.n_rows(), n_comp));
+    Assert (int_mask.n_cols() == n_comp,
+            ExcDimensionMismatch (int_mask.n_cols(), n_comp));
+    Assert (flux_mask.n_rows() == n_comp,
+            ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
+    Assert (flux_mask.n_cols() == n_comp,
+            ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
+
+    // Clear user flags because we will need them. But first we save them
+    // and make sure that we restore them later such that at the end of
+    // this function the Triangulation will be in the same state as it was
+    // at the beginning of this function.
+    std::vector<bool> user_flags;
+    dof.get_tria().save_user_flags(user_flags);
+    const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).clear_user_flags ();
+
+    internal::make_flux_sparsity_pattern (dof, sparsity,
+                                          int_mask, flux_mask);
+
+    // finally restore the user flags
+    const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).load_user_flags(user_flags);
+  }
+
+
+} // end of namespace DoFTools
+
+
+// --------------------------------------------------- explicit instantiations
+
+#include "dof_tools_sparsity.inst"
+
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/dofs/dof_tools_sparsity.inst.in b/deal.II/source/dofs/dof_tools_sparsity.inst.in
new file mode 100644 (file)
index 0000000..6781dbe
--- /dev/null
@@ -0,0 +1,323 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2009 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (SP : SPARSITY_PATTERNS; deal_II_dimension : DIMENSIONS)
+  {
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<MGDoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const MGDoFHandler<deal_II_dimension,deal_II_dimension> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<MGDoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const MGDoFHandler<deal_II_dimension,deal_II_dimension>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension> &dof_row,
+     const DoFHandler<deal_II_dimension,deal_II_dimension> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof_row,
+     const hp::DoFHandler<deal_II_dimension,deal_II_dimension> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
+    (const DoFHandler<deal_II_dimension>& dof,
+     const std::vector<types::global_dof_index>  &,
+     SP    &);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
+    (const hp::DoFHandler<deal_II_dimension>& dof,
+     const std::vector<types::global_dof_index>  &,
+     SP    &);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
+    (const DoFHandler<deal_II_dimension>& dof,
+     const FunctionMap<deal_II_dimension>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
+    (const hp::DoFHandler<deal_II_dimension>& dof,
+     const FunctionMap<deal_II_dimension>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+
+#if deal_II_dimension < 3
+    template void
+    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+     const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+ #endif
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
+    (const DoFHandler<deal_II_dimension> &dof,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
+    (const hp::DoFHandler<deal_II_dimension> &dof,
+     SP    &sparsity);
+
+#if deal_II_dimension > 1
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
+    (const DoFHandler<deal_II_dimension> &dof,
+     SP    &,
+     const Table<2,Coupling>&,
+     const Table<2,Coupling>&);
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<DoFHandler<deal_II_dimension>,SP>
+    (const DoFHandler<deal_II_dimension> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &constraints,
+     const bool, const unsigned int);
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
+    (const hp::DoFHandler<deal_II_dimension> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &constraints,
+     const bool, const unsigned int);
+
+    template void
+    DoFTools::make_flux_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,SP>
+    (const hp::DoFHandler<deal_II_dimension> &dof,
+     SP    &,
+     const Table<2,Coupling>&,
+     const Table<2,Coupling>&);
+#endif
+
+#if deal_II_dimension < 3
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+     const DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>, SP>
+    (const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_row,
+     const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+     const std::vector<types::global_dof_index>  &,
+     SP    &);
+
+    //template void
+    //DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
+    //(const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+    // const std::vector<types::global_dof_index>  &,
+    // SP    &);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
+    (const DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+     const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+
+    //template void
+    //DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>,SP>
+    //(const hp::DoFHandler<deal_II_dimension,deal_II_dimension+1>& dof,
+    // const FunctionMap<deal_II_dimension+1>::type  &boundary_indicators,
+    // const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+    // SP    &sparsity);
+
+#endif
+
+
+#if deal_II_dimension == 3
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
+    (const DoFHandler<1,3> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
+    (const hp::DoFHandler<1,3> &dof,
+     SP    &sparsity,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
+    (const DoFHandler<1,3>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
+    (const hp::DoFHandler<1,3>&,
+     const Table<2,Coupling>&,
+     SP &,
+     const ConstraintMatrix &,
+     const bool,
+     const unsigned int);
+
+    template void
+    DoFTools::make_sparsity_pattern<DoFHandler<1,3>, SP>
+    (const DoFHandler<1,3> &dof_row,
+     const DoFHandler<1,3> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_sparsity_pattern<hp::DoFHandler<1,3>, SP>
+    (const hp::DoFHandler<1,3> &dof_row,
+     const hp::DoFHandler<1,3> &dof_col,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<1,3>,SP>
+    (const DoFHandler<1,3>& dof,
+     const std::vector<types::global_dof_index>  &,
+     SP    &);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<1,3>,SP>
+    (const hp::DoFHandler<1,3>& dof,
+     const std::vector<types::global_dof_index>  &,
+     SP    &);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<DoFHandler<1,3>,SP>
+    (const DoFHandler<1,3>& dof,
+     const FunctionMap<3>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+
+    template void
+    DoFTools::make_boundary_sparsity_pattern<hp::DoFHandler<1,3>,SP>
+    (const hp::DoFHandler<1,3>& dof,
+     const FunctionMap<3>::type  &boundary_indicators,
+     const std::vector<types::global_dof_index>  &dof_to_boundary_mapping,
+     SP    &sparsity);
+
+#endif
+
+  }
+
+
+for (deal_II_dimension : DIMENSIONS)
+{
+  template
+  Table<2,DoFTools::Coupling>
+  DoFTools::dof_couplings_from_component_couplings
+  (const FiniteElement<deal_II_dimension> &fe,
+   const Table<2,DoFTools::Coupling> &component_couplings);
+}
index 5604f193392dacd016e7b2df5e3153a32e3716c5..5fa933789b6e30239b10de0aacc9ad6d3cd901ee 100644 (file)
@@ -46,6 +46,7 @@ SET(_src
   fe_raviart_thomas_nodal.cc
   fe_system.cc
   fe_tools.cc
+  fe_tools_interpolate.cc
   fe_values.cc
   fe_values_inst2.cc
   mapping_c1.cc
@@ -80,6 +81,7 @@ SET(_inst
   fe_raviart_thomas_nodal.inst.in
   fe_system.inst.in
   fe_tools.inst.in
+  fe_tools_interpolate.inst.in
   fe_values.decl.1.inst.in
   fe_values.decl.2.inst.in
   fe_values.impl.1.inst.in
index 501e7e0d818874bfe071b15856a0bdcc6013b89f..1c4db8ffbc8f7a883195b73d923494b5436bb9d9 100644 (file)
@@ -190,16 +190,16 @@ FiniteElement<dim,spacedim>::FiniteElement (
       system_to_component_table.resize(this->dofs_per_cell);
       face_system_to_component_table.resize(this->dofs_per_face);
       for (unsigned int j=0 ; j<this->dofs_per_cell ; ++j)
-        {
-          system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
-          system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
-        }
+       system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
       for (unsigned int j=0 ; j<this->dofs_per_face ; ++j)
-        {
-          face_system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
-          face_system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
-        }
+       face_system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
     }
+  
+  for (unsigned int j=0 ; j<this->dofs_per_cell ; ++j)
+    system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
+  for (unsigned int j=0 ; j<this->dofs_per_face ; ++j)
+    face_system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
+  
   // Fill with default value; may be changed by constructor of derived class.
   base_to_block_indices.reinit(1,1);
 
index a43e3be528b3c054cf27988f54a2efea188ce3ec..6a73cb86ffc7205adf8168e91502a6d0ff8eed2f 100644 (file)
@@ -459,71 +459,90 @@ FE_Q_Base<POLY,dim,spacedim>::
 get_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
                           FullMatrix<double>       &interpolation_matrix) const
 {
-  // this is only implemented, if the source FE is also a Q element
-  AssertThrow ((dynamic_cast<const FE_Q_Base<POLY,dim,spacedim> *>(&x_source_fe) != 0),
-               (typename FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented()));
+  // go through the list of elements we can interpolate from
+  if (const FE_Q_Base<POLY,dim,spacedim> *source_fe
+      = dynamic_cast<const FE_Q_Base<POLY,dim,spacedim>*>(&x_source_fe))
+    {
+      // ok, source is a Q element, so we will be able to do the work
+      Assert (interpolation_matrix.m() == this->dofs_per_cell,
+              ExcDimensionMismatch (interpolation_matrix.m(),
+                                    this->dofs_per_cell));
+      Assert (interpolation_matrix.n() == x_source_fe.dofs_per_cell,
+              ExcDimensionMismatch (interpolation_matrix.m(),
+                                    x_source_fe.dofs_per_cell));
+
+      // only evaluate Q dofs
+      const unsigned int q_dofs_per_cell = Utilities::fixed_power<dim>(this->degree+1);
+      const unsigned int source_q_dofs_per_cell = Utilities::fixed_power<dim>(source_fe->degree+1);
 
-  Assert (interpolation_matrix.m() == this->dofs_per_cell,
-          ExcDimensionMismatch (interpolation_matrix.m(),
-                                this->dofs_per_cell));
-  Assert (interpolation_matrix.n() == x_source_fe.dofs_per_cell,
-          ExcDimensionMismatch (interpolation_matrix.m(),
-                                x_source_fe.dofs_per_cell));
+      // evaluation is simply done by evaluating the other FE's basis functions on
+      // the unit support points (FE_Q has the property that the cell
+      // interpolation matrix is a unit matrix, so no need to evaluate it and
+      // invert it)
+      for (unsigned int j=0; j<q_dofs_per_cell; ++j)
+        {
+          // read in a point on this cell and evaluate the shape functions there
+          const Point<dim> p = this->unit_support_points[j];
 
-  // ok, source is a Q element, so we will be able to do the work
-  const FE_Q_Base<POLY,dim,spacedim> &source_fe
-    = dynamic_cast<const FE_Q_Base<POLY,dim,spacedim>&>(x_source_fe);
+          // FE_Q element evaluates to 1 in unit support point and to zero in all
+          // other points by construction
+          Assert(std::abs(this->poly_space.compute_value (j, p)-1.)<1e-13,
+                 ExcInternalError());
 
-  // only evaluate Q dofs
-  const unsigned int q_dofs_per_cell = Utilities::fixed_power<dim>(this->degree+1);
-  const unsigned int source_q_dofs_per_cell = Utilities::fixed_power<dim>(source_fe.degree+1);
+          for (unsigned int i=0; i<source_q_dofs_per_cell; ++i)
+            interpolation_matrix(j,i) = source_fe->poly_space.compute_value (i, p);
+        }
 
-  // evaluation is simply done by evaluating the other FE's basis functions on
-  // the unit support points (FE_Q has the property that the cell
-  // interpolation matrix is a unit matrix, so no need to evaluate it and
-  // invert it)
-  for (unsigned int j=0; j<q_dofs_per_cell; ++j)
-    {
-      // read in a point on this cell and evaluate the shape functions there
-      const Point<dim> p = this->unit_support_points[j];
+      // for FE_Q_DG0, add one last row of identity
+      if (q_dofs_per_cell < this->dofs_per_cell)
+        {
+          AssertDimension(source_q_dofs_per_cell+1, source_fe->dofs_per_cell);
+          for (unsigned int i=0; i<source_q_dofs_per_cell; ++i)
+            interpolation_matrix(q_dofs_per_cell, i) = 0.;
+          for (unsigned int j=0; j<q_dofs_per_cell; ++j)
+            interpolation_matrix(j, source_q_dofs_per_cell) = 0.;
+          interpolation_matrix(q_dofs_per_cell, source_q_dofs_per_cell) = 1.;
+        }
 
-      // FE_Q element evaluates to 1 in unit support point and to zero in all
-      // other points by construction
-      Assert(std::abs(this->poly_space.compute_value (j, p)-1.)<1e-13,
-             ExcInternalError());
+      // cut off very small values
+      const double eps = 2e-13*this->degree*dim;
+      for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+        for (unsigned int j=0; j<source_fe->dofs_per_cell; ++j)
+          if (std::fabs(interpolation_matrix(i,j)) < eps)
+            interpolation_matrix(i,j) = 0.;
 
-      for (unsigned int i=0; i<source_q_dofs_per_cell; ++i)
-        interpolation_matrix(j,i) = source_fe.poly_space.compute_value (i, p);
-    }
+      // make sure that the row sum of each of the matrices is 1 at this
+      // point. this must be so since the shape functions sum up to 1
+      for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+        {
+          double sum = 0.;
+          for (unsigned int j=0; j<source_fe->dofs_per_cell; ++j)
+            sum += interpolation_matrix(i,j);
 
-  // for FE_Q_DG0, add one last row of identity
-  if (q_dofs_per_cell < this->dofs_per_cell)
-    {
-      AssertDimension(source_q_dofs_per_cell+1, source_fe.dofs_per_cell);
-      for (unsigned int i=0; i<source_q_dofs_per_cell; ++i)
-        interpolation_matrix(q_dofs_per_cell, i) = 0.;
-      for (unsigned int j=0; j<q_dofs_per_cell; ++j)
-        interpolation_matrix(j, source_q_dofs_per_cell) = 0.;
-      interpolation_matrix(q_dofs_per_cell, source_q_dofs_per_cell) = 1.;
+          Assert (std::fabs(sum-1) < eps, ExcInternalError());
+        }
     }
-
-  // cut off very small values
-  const double eps = 2e-13*this->degree*dim;
-  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
-    for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
-      if (std::fabs(interpolation_matrix(i,j)) < eps)
-        interpolation_matrix(i,j) = 0.;
-
-  // make sure that the row sum of each of the matrices is 1 at this
-  // point. this must be so since the shape functions sum up to 1
-  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+  else if (dynamic_cast<const FE_Nothing<dim>*>(&x_source_fe))
     {
-      double sum = 0.;
-      for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
-        sum += interpolation_matrix(i,j);
+      // the element we want to interpolate from is an FE_Nothing. this
+      // element represents a function that is constant zero and has no
+      // degrees of freedom, so the interpolation is simply a multiplication
+      // with a n_dofs x 0 matrix. there is nothing to do here
+
+      // we would like to verify that the number of rows and columns of
+      // the matrix equals this->dofs_per_cell and zero. unfortunately,
+      // whenever we do FullMatrix::reinit(m,0), it sets both rows and
+      // columns to zero, instead of m and zero. thus, only test the
+      // number of columns
+      Assert (interpolation_matrix.n() == x_source_fe.dofs_per_cell,
+              ExcDimensionMismatch (interpolation_matrix.m(),
+                                    x_source_fe.dofs_per_cell));
 
-      Assert (std::fabs(sum-1) < eps, ExcInternalError());
     }
+  else
+    AssertThrow (false,
+                 (typename FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented()));
+
 }
 
 
index fe6be9fd8c2b0bdd6c0d62ebb23f5f3d987faf2c..4ba84c5a43c057826d4159b9a0df13f1fd4dabd3 100644 (file)
 #include <deal.II/base/utilities.h>
 #include <deal.II/lac/full_matrix.h>
 #include <deal.II/lac/householder.h>
-#include <deal.II/lac/vector.h>
-#include <deal.II/lac/block_vector.h>
-#include <deal.II/lac/parallel_vector.h>
-#include <deal.II/lac/parallel_block_vector.h>
-#include <deal.II/lac/petsc_parallel_vector.h>
-#include <deal.II/lac/petsc_block_vector.h>
-#include <deal.II/lac/petsc_parallel_block_vector.h>
-#include <deal.II/lac/trilinos_vector.h>
-#include <deal.II/lac/trilinos_block_vector.h>
 #include <deal.II/lac/constraint_matrix.h>
 #include <deal.II/grid/tria.h>
 #include <deal.II/grid/tria_iterator.h>
@@ -399,8 +390,7 @@ namespace FETools
           start_indices[i] = k;
           k += block_data[i];
         }
-
-//TODO:[GK] This does not work for a single RT
+    
     for (unsigned int i=0; i<element.dofs_per_cell; ++i)
       {
         std::pair<unsigned int, types::global_dof_index>
@@ -1271,703 +1261,6 @@ namespace FETools
   }
 
 
-  template <int dim, int spacedim,
-           template <int, int> class DH1,
-           template <int, int> class DH2,
-           class InVector, class OutVector>
-  void
-  interpolate(const DH1<dim, spacedim> &dof1,
-              const InVector           &u1,
-              const DH2<dim, spacedim> &dof2,
-              OutVector                &u2)
-  {
-    ConstraintMatrix dummy;
-    dummy.close();
-    interpolate(dof1, u1, dof2, dummy, u2);
-  }
-
-
-
-  template <int dim, int spacedim,
-           template <int, int> class DH1,
-           template <int, int> class DH2,
-           class InVector, class OutVector>
-  void
-  interpolate (const DH1<dim, spacedim> &dof1,
-               const InVector           &u1,
-               const DH2<dim, spacedim> &dof2,
-               const ConstraintMatrix   &constraints,
-               OutVector                &u2)
-  {
-    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
-
-    Assert(u1.size()==dof1.n_dofs(),
-           ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u2.size()==dof2.n_dofs(),
-           ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
-
-#ifdef DEAL_II_WITH_PETSC
-    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          // if u1 is a parallel distributed
-          // PETSc vector, we check the local
-          // size of u1 for safety
-          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-
-    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u2) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof2) != 0)
-        {
-          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size() == dof2.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size(), dof2.locally_owned_dofs().n_elements()));
-        };
-#endif
-    // allocate vectors at maximal
-    // size. will be reinited in inner
-    // cell, but Vector makes sure that
-    // this does not lead to
-    // reallocation of memory
-    Vector<typename OutVector::value_type> u1_local(DoFTools::max_dofs_per_cell(dof1));
-    Vector<typename OutVector::value_type> u2_local(DoFTools::max_dofs_per_cell(dof2));
-
-    // have a map for interpolation
-    // matrices. shared_ptr make sure
-    // that memory is released again
-    std::map<const FiniteElement<dim,spacedim> *,
-        std::map<const FiniteElement<dim,spacedim> *,
-        std_cxx1x::shared_ptr<FullMatrix<double> > > >
-        interpolation_matrices;
-
-    typename DH1<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active(),
-                                                     endc1 = dof1.end();
-    typename DH2<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active(),
-                                                     endc2 = dof2.end();
-
-    std::vector<types::global_dof_index> dofs;
-    dofs.reserve (DoFTools::max_dofs_per_cell (dof2));
-
-    u2 = 0;
-    OutVector touch_count(u2);
-    touch_count = 0;
-
-    // for distributed triangulations,
-    // we can only interpolate u1 on
-    // a cell, which this processor owns,
-    // so we have to know the subdomain_id
-    const types::subdomain_id subdomain_id =
-      dof1.get_tria().locally_owned_subdomain();
-
-    for (; cell1!=endc1; ++cell1, ++cell2)
-      if ((cell1->subdomain_id() == subdomain_id)
-          ||
-          (subdomain_id == numbers::invalid_subdomain_id))
-        {
-          Assert(cell1->get_fe().n_components() == cell2->get_fe().n_components(),
-                 ExcDimensionMismatch (cell1->get_fe().n_components(),
-                                       cell2->get_fe().n_components()));
-
-          // for continuous elements on
-          // grids with hanging nodes we
-          // need hanging node
-          // constraints. Consequentely,
-          // if there are no constraints
-          // then hanging nodes are not
-          // allowed.
-          const bool hanging_nodes_not_allowed
-            = ((cell2->get_fe().dofs_per_vertex != 0) &&
-               (constraints.n_constraints() == 0));
-
-          if (hanging_nodes_not_allowed)
-            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-              Assert (cell1->at_boundary(face) ||
-                      cell1->neighbor(face)->level() == cell1->level(),
-                      ExcHangingNodesNotAllowed(0));
-
-
-          const unsigned int dofs_per_cell1 = cell1->get_fe().dofs_per_cell;
-          const unsigned int dofs_per_cell2 = cell2->get_fe().dofs_per_cell;
-          u1_local.reinit (dofs_per_cell1);
-          u2_local.reinit (dofs_per_cell2);
-
-          // check if interpolation
-          // matrix for this particular
-          // pair of elements is already
-          // there
-          if (interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()].get() == 0)
-            {
-              std_cxx1x::shared_ptr<FullMatrix<double> >
-              interpolation_matrix (new FullMatrix<double> (dofs_per_cell2,
-                                                            dofs_per_cell1));
-              interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
-                = interpolation_matrix;
-
-              get_interpolation_matrix(cell1->get_fe(),
-                                       cell2->get_fe(),
-                                       *interpolation_matrix);
-            }
-
-          cell1->get_dof_values(u1, u1_local);
-          interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
-          ->vmult(u2_local, u1_local);
-
-          dofs.resize (dofs_per_cell2);
-          cell2->get_dof_indices(dofs);
-
-          for (unsigned int i=0; i<dofs_per_cell2; ++i)
-            {
-              u2(dofs[i])+=u2_local(i);
-              touch_count(dofs[i]) += 1;
-            }
-        }
-    // cell1 is at the end, so should
-    // be cell2
-    Assert (cell2 == endc2, ExcInternalError());
-
-    u2.compress(VectorOperation::add);
-    touch_count.compress(VectorOperation::add);
-
-    // if we work on parallel distributed
-    // vectors, we have to ensure, that we only
-    // work on dofs this processor owns.
-    IndexSet  locally_owned_dofs = dof2.locally_owned_dofs();
-
-    // when a discontinuous element is
-    // interpolated to a continuous
-    // one, we take the mean values.
-    // for parallel vectors check,
-    // if this component is owned by
-    // this processor.
-    for (types::global_dof_index i=0; i<dof2.n_dofs(); ++i)
-      if (locally_owned_dofs.is_element(i))
-        {
-          Assert(touch_count(i)!=0, ExcInternalError());
-          u2(i) /= touch_count(i);
-        }
-
-    // finish the work on parallel vectors
-    u2.compress(VectorOperation::insert);
-    // Apply hanging node constraints.
-    constraints.distribute(u2);
-  }
-
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void
-  back_interpolate(const DoFHandler<dim,spacedim>    &dof1,
-                   const InVector           &u1,
-                   const FiniteElement<dim,spacedim> &fe2,
-                   OutVector                &u1_interpolated)
-  {
-    Assert(dof1.get_fe().n_components() == fe2.n_components(),
-           ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
-    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u1_interpolated.size()==dof1.n_dofs(),
-           ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
-
-#ifdef DEAL_II_WITH_PETSC
-    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          // if u1 is a parallel distributed
-          // PETSc vector, we check the local
-          // size of u1 for safety
-          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-
-    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-#endif
-
-    // For continuous elements on grids
-    // with hanging nodes we need
-    // hanging node
-    // constraints. Consequently, when
-    // the elements are continuous no
-    // hanging node constraints are
-    // allowed.
-    const bool hanging_nodes_not_allowed=
-      (dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
-
-    const unsigned int dofs_per_cell1=dof1.get_fe().dofs_per_cell;
-
-    Vector<typename OutVector::value_type> u1_local(dofs_per_cell1);
-    Vector<typename OutVector::value_type> u1_int_local(dofs_per_cell1);
-
-    const types::subdomain_id subdomain_id =
-      dof1.get_tria().locally_owned_subdomain();
-
-    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
-                                                            endc = dof1.end();
-
-    FullMatrix<double> interpolation_matrix(dofs_per_cell1, dofs_per_cell1);
-    get_back_interpolation_matrix(dof1.get_fe(), fe2,
-                                  interpolation_matrix);
-    for (; cell!=endc; ++cell)
-      if ((cell->subdomain_id() == subdomain_id)
-          ||
-          (subdomain_id == numbers::invalid_subdomain_id))
-        {
-          if (hanging_nodes_not_allowed)
-            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-              Assert (cell->at_boundary(face) ||
-                      cell->neighbor(face)->level() == cell->level(),
-                      ExcHangingNodesNotAllowed(0));
-
-          cell->get_dof_values(u1, u1_local);
-          interpolation_matrix.vmult(u1_int_local, u1_local);
-          cell->set_dof_values(u1_int_local, u1_interpolated);
-        }
-
-    // if we work on a parallel PETSc vector
-    // we have to finish the work
-    u1_interpolated.compress(VectorOperation::insert);
-  }
-
-
-
-  template <int dim,
-           template <int> class DH,
-           class InVector, class OutVector, int spacedim>
-  void
-  back_interpolate(const DH<dim>            &dof1,
-                   const InVector           &u1,
-                   const FiniteElement<dim,spacedim> &fe2,
-                   OutVector                &u1_interpolated)
-  {
-    Assert(u1.size() == dof1.n_dofs(),
-           ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u1_interpolated.size() == dof1.n_dofs(),
-           ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
-
-#ifdef DEAL_II_WITH_PETSC
-    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          // if u1 is a parallel distributed
-          // PETSc vector, we check the local
-          // size of u1 for safety
-          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-
-    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-#endif
-
-    Vector<typename OutVector::value_type> u1_local(DoFTools::max_dofs_per_cell(dof1));
-    Vector<typename OutVector::value_type> u1_int_local(DoFTools::max_dofs_per_cell(dof1));
-
-    const types::subdomain_id subdomain_id =
-      dof1.get_tria().locally_owned_subdomain();
-
-    typename DH<dim>::active_cell_iterator cell = dof1.begin_active(),
-                                           endc = dof1.end();
-
-    // map from possible fe objects in
-    // dof1 to the back_interpolation
-    // matrices
-    std::map<const FiniteElement<dim> *,
-        std_cxx1x::shared_ptr<FullMatrix<double> > > interpolation_matrices;
-
-    for (; cell!=endc; ++cell)
-      if ((cell->subdomain_id() == subdomain_id)
-          ||
-          (subdomain_id == numbers::invalid_subdomain_id))
-        {
-          Assert(cell->get_fe().n_components() == fe2.n_components(),
-                 ExcDimensionMismatch(cell->get_fe().n_components(),
-                                      fe2.n_components()));
-
-          // For continuous elements on
-          // grids with hanging nodes we
-          // need hanging node
-          // constraints. Consequently,
-          // when the elements are
-          // continuous no hanging node
-          // constraints are allowed.
-          const bool hanging_nodes_not_allowed=
-            (cell->get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
-
-          if (hanging_nodes_not_allowed)
-            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-              Assert (cell->at_boundary(face) ||
-                      cell->neighbor(face)->level() == cell->level(),
-                      ExcHangingNodesNotAllowed(0));
-
-          const unsigned int dofs_per_cell1 = cell->get_fe().dofs_per_cell;
-
-          // make sure back_interpolation
-          // matrix is available
-          if (interpolation_matrices[&cell->get_fe()] != 0)
-            {
-              interpolation_matrices[&cell->get_fe()] =
-                std_cxx1x::shared_ptr<FullMatrix<double> >
-                (new FullMatrix<double>(dofs_per_cell1, dofs_per_cell1));
-              get_back_interpolation_matrix(dof1.get_fe(), fe2,
-                                            *interpolation_matrices[&cell->get_fe()]);
-            }
-
-          u1_local.reinit (dofs_per_cell1);
-          u1_int_local.reinit (dofs_per_cell1);
-
-          cell->get_dof_values(u1, u1_local);
-          interpolation_matrices[&cell->get_fe()]->vmult(u1_int_local, u1_local);
-          cell->set_dof_values(u1_int_local, u1_interpolated);
-        };
-
-    // if we work on a parallel PETSc vector
-    // we have to finish the work
-    u1_interpolated.compress(VectorOperation::insert);
-  }
-
-
-
-  namespace internal
-  {
-    namespace
-    {
-      template <int dim, int spacedim, class InVector>
-      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
-                             const ConstraintMatrix &constraints1,
-                             const InVector &u1,
-                             const DoFHandler<dim,spacedim> &dof2,
-                             const ConstraintMatrix &constraints2,
-                             InVector &u1_interpolated)
-      {
-        Vector<typename InVector::value_type> u2(dof2.n_dofs());
-        interpolate(dof1, u1, dof2, constraints2, u2);
-        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
-      }
-
-      // special version for PETSc
-#ifdef DEAL_II_WITH_PETSC
-      template <int dim, int spacedim>
-      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
-                             const ConstraintMatrix &constraints1,
-                             const PETScWrappers::MPI::Vector &u1,
-                             const DoFHandler<dim,spacedim> &dof2,
-                             const ConstraintMatrix &constraints2,
-                             PETScWrappers::MPI::Vector &u1_interpolated)
-      {
-        // if u1 is a parallel distributed PETSc vector, we create a
-        // vector u2 with based on the sets of locally owned and relevant
-        // dofs of dof2
-        IndexSet  dof2_locally_owned_dofs = dof2.locally_owned_dofs();
-        IndexSet  dof2_locally_relevant_dofs;
-        DoFTools::extract_locally_relevant_dofs (dof2,
-                                                 dof2_locally_relevant_dofs);
-
-        PETScWrappers::MPI::Vector  u2_out (u1.get_mpi_communicator(),
-                                            dof2_locally_owned_dofs);
-        interpolate(dof1, u1, dof2, constraints2, u2_out);
-        PETScWrappers::MPI::Vector  u2 (u1.get_mpi_communicator(),
-                                        dof2_locally_owned_dofs,
-                                        dof2_locally_relevant_dofs);
-        u2 = u2_out;
-        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
-      }
-#endif
-
-      // special version for parallel::distributed::Vector
-      template <int dim, int spacedim, typename Number>
-      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
-                             const ConstraintMatrix &constraints1,
-                             const parallel::distributed::Vector<Number> &u1,
-                             const DoFHandler<dim,spacedim> &dof2,
-                             const ConstraintMatrix &constraints2,
-                             parallel::distributed::Vector<Number> &u1_interpolated)
-      {
-        IndexSet dof2_locally_owned_dofs = dof2.locally_owned_dofs();
-        IndexSet dof2_locally_relevant_dofs;
-        DoFTools::extract_locally_relevant_dofs (dof2,
-                                                 dof2_locally_relevant_dofs);
-
-        parallel::distributed::Vector<Number>
-        u2 (dof2_locally_owned_dofs,
-            dof2_locally_relevant_dofs,
-            u1.get_mpi_communicator());
-
-        interpolate(dof1, u1, dof2, constraints2, u2);
-        u2.update_ghost_values ();
-        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
-      }
-    }
-  }
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void back_interpolate(const DoFHandler<dim,spacedim> &dof1,
-                        const ConstraintMatrix &constraints1,
-                        const InVector &u1,
-                        const DoFHandler<dim,spacedim> &dof2,
-                        const ConstraintMatrix &constraints2,
-                        OutVector &u1_interpolated)
-  {
-    // For discontinuous elements without constraints take the simpler version
-    // of the back_interpolate function.
-    if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
-        && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
-      back_interpolate(dof1, u1, dof2.get_fe(), u1_interpolated);
-    else
-      {
-        Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
-               ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
-        Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-        Assert(u1_interpolated.size()==dof1.n_dofs(),
-               ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
-
-        // For continuous elements first interpolate to dof2, taking into
-        // account constraints2, and then interpolate back to dof1 taking into
-        // account constraints1
-        internal::back_interpolate(dof1, constraints1, u1, dof2, constraints2,
-                                   u1_interpolated);
-      }
-  }
-
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
-                                 const InVector &u1,
-                                 const FiniteElement<dim,spacedim> &fe2,
-                                 OutVector &u1_difference)
-  {
-    Assert(dof1.get_fe().n_components() == fe2.n_components(),
-           ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
-    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u1_difference.size()==dof1.n_dofs(),
-           ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs()));
-
-#ifdef DEAL_II_WITH_PETSC
-    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          // if u1 is a parallel distributed
-          // PETSc vector, we check the local
-          // size of u1 for safety
-          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-
-    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference) != 0)
-      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
-        {
-          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size() == dof1.locally_owned_dofs().n_elements(),
-                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size(), dof1.locally_owned_dofs().n_elements()));
-        };
-#endif
-
-    // For continuous elements on grids
-    // with hanging nodes we need
-    // hanging node
-    // constraints. Consequently, when
-    // the elements are continuous no
-    // hanging node constraints are
-    // allowed.
-    const bool hanging_nodes_not_allowed=
-      (dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
-
-    const unsigned int dofs_per_cell=dof1.get_fe().dofs_per_cell;
-
-    Vector<typename OutVector::value_type> u1_local(dofs_per_cell);
-    Vector<typename OutVector::value_type> u1_diff_local(dofs_per_cell);
-
-    const types::subdomain_id subdomain_id =
-      dof1.get_tria().locally_owned_subdomain();
-
-    FullMatrix<double> difference_matrix(dofs_per_cell, dofs_per_cell);
-    get_interpolation_difference_matrix(dof1.get_fe(), fe2,
-                                        difference_matrix);
-
-    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
-                                                            endc = dof1.end();
-
-    for (; cell!=endc; ++cell)
-      if ((cell->subdomain_id() == subdomain_id)
-          ||
-          (subdomain_id == numbers::invalid_subdomain_id))
-        {
-          if (hanging_nodes_not_allowed)
-            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-              Assert (cell->at_boundary(face) ||
-                      cell->neighbor(face)->level() == cell->level(),
-                      ExcHangingNodesNotAllowed(0));
-
-          cell->get_dof_values(u1, u1_local);
-          difference_matrix.vmult(u1_diff_local, u1_local);
-          cell->set_dof_values(u1_diff_local, u1_difference);
-        }
-
-    // if we work on a parallel PETSc vector
-    // we have to finish the work and
-    // update ghost values
-    u1_difference.compress(VectorOperation::insert);
-  }
-
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
-                                const ConstraintMatrix &constraints1,
-                                const InVector &u1,
-                                const DoFHandler<dim,spacedim> &dof2,
-                                const ConstraintMatrix &constraints2,
-                                OutVector &u1_difference)
-  {
-    // For discontinuous elements
-    // without constraints take the
-    // cheaper version of the
-    // interpolation_difference function.
-    if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
-        && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
-      interpolation_difference(dof1, u1, dof2.get_fe(), u1_difference);
-    else
-      {
-        back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
-        u1_difference.sadd(-1, u1);
-      }
-  }
-
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void project_dg(const DoFHandler<dim,spacedim> &dof1,
-                  const InVector &u1,
-                  const DoFHandler<dim,spacedim> &dof2,
-                  OutVector &u2)
-  {
-    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
-    Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
-           ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
-    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
-
-    typename DoFHandler<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active();
-    typename DoFHandler<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active();
-    typename DoFHandler<dim,spacedim>::active_cell_iterator end = dof2.end();
-
-    const unsigned int n1 = dof1.get_fe().dofs_per_cell;
-    const unsigned int n2 = dof2.get_fe().dofs_per_cell;
-
-    Vector<double> u1_local(n1);
-    Vector<double> u2_local(n2);
-    std::vector<types::global_dof_index> dofs(n2);
-
-    FullMatrix<double> matrix(n2,n1);
-    get_projection_matrix(dof1.get_fe(), dof2.get_fe(), matrix);
-
-    while (cell2 != end)
-      {
-        cell1->get_dof_values(u1, u1_local);
-        matrix.vmult(u2_local, u1_local);
-        cell2->get_dof_indices(dofs);
-        for (unsigned int i=0; i<n2; ++i)
-          {
-            u2(dofs[i])+=u2_local(i);
-          }
-
-        ++cell1;
-        ++cell2;
-      }
-  }
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void extrapolate(const DoFHandler<dim,spacedim> &dof1,
-                   const InVector &u1,
-                   const DoFHandler<dim,spacedim> &dof2,
-                   OutVector &u2)
-  {
-    ConstraintMatrix dummy;
-    dummy.close();
-    extrapolate(dof1, u1, dof2, dummy, u2);
-  }
-
-
-
-  template <int dim, class InVector, class OutVector, int spacedim>
-  void extrapolate(const DoFHandler<dim,spacedim> &dof1,
-                   const InVector &u1,
-                   const DoFHandler<dim,spacedim> &dof2,
-                   const ConstraintMatrix &constraints,
-                   OutVector &u2)
-  {
-    Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
-           ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
-    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
-    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
-    Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
-
-    OutVector u3;
-    u3.reinit(u2);
-    interpolate(dof1, u1, dof2, constraints, u3);
-
-    const unsigned int dofs_per_cell  = dof2.get_fe().dofs_per_cell;
-    Vector<typename OutVector::value_type> dof_values(dofs_per_cell);
-
-    // make sure that each cell on the
-    // coarsest level is at least once
-    // refined. otherwise, we can't
-    // treat these cells and would
-    // generate a bogus result
-    {
-      typename DoFHandler<dim,spacedim>::cell_iterator cell = dof2.begin(0),
-                                                       endc = dof2.end(0);
-      for (; cell!=endc; ++cell)
-        Assert (cell->has_children(), ExcGridNotRefinedAtLeastOnce());
-    }
-
-    // then traverse grid bottom up
-    for (unsigned int level=0; level<dof1.get_tria().n_levels()-1; ++level)
-      {
-        typename DoFHandler<dim,spacedim>::cell_iterator cell=dof2.begin(level),
-                                                         endc=dof2.end(level);
-
-        for (; cell!=endc; ++cell)
-          if (!cell->active())
-            {
-              // check whether this
-              // cell has active
-              // children
-              bool active_children=false;
-              for (unsigned int child_n=0; child_n<cell->n_children(); ++child_n)
-                if (cell->child(child_n)->active())
-                  {
-                    active_children=true;
-                    break;
-                  }
-
-              // if there are active
-              // children, the we have
-              // to work on this
-              // cell. get the data
-              // from the one vector
-              // and set it on the
-              // other
-              if (active_children)
-                {
-                  cell->get_interpolated_dof_values(u3, dof_values);
-                  cell->set_dof_values_by_interpolation(dof_values, u2);
-                }
-            }
-      }
-
-    // Apply hanging node constraints.
-    constraints.distribute(u2);
-  }
-
 
   template <>
   void
@@ -2850,7 +2143,7 @@ namespace FETools
     return Utilities::invert_permutation(hierarchic_to_lexicographic_numbering (fe));
   }
 
-}
+} // end of namespace FETools
 
 
 
index 081a3274851ccf2dae74a559afde59c4c52338ca..3809bdd380bed56c88d4c3aed02c757cd0ef915d 100644 (file)
 // ---------------------------------------------------------------------
 
 
-
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS; Vector : SERIAL_VECTORS)
-  {
-    namespace FETools
-      \{
-#if deal_II_dimension <= deal_II_space_dimension
-      template
-       void interpolate<deal_II_dimension,deal_II_space_dimension>
-       (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const Vector &,
-        const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, Vector &);
-
-      template
-       void interpolate<deal_II_dimension,deal_II_space_dimension>
-       (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const Vector &,
-        const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const ConstraintMatrix &,
-        Vector &);
-#endif
-      \}
-  }
-
 for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
   {
     namespace FETools
@@ -67,6 +47,15 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
   {
     namespace FETools
       \{
+  
+#if deal_II_dimension <= deal_II_space_dimension
+      template
+       void get_interpolation_matrix<deal_II_dimension,double,deal_II_space_dimension>
+       (const FiniteElement<deal_II_dimension,deal_II_space_dimension> &,
+        const FiniteElement<deal_II_dimension,deal_II_space_dimension> &,
+        FullMatrix<double> &);
+#endif
+
 #if deal_II_dimension == deal_II_space_dimension
 
       template class FEFactoryBase<deal_II_dimension>;
@@ -80,12 +69,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
        void compute_component_wise(
          const FiniteElement<deal_II_dimension>& ,
          std::vector<unsigned int>&, std::vector<std::vector<unsigned int> >&);
-      template
-  
-       void get_interpolation_matrix<deal_II_dimension>
-       (const FiniteElement<deal_II_dimension> &,
-        const FiniteElement<deal_II_dimension> &,
-        FullMatrix<double> &);
+
       template
        void get_back_interpolation_matrix<deal_II_dimension>
        (const FiniteElement<deal_II_dimension> &,
@@ -125,25 +109,6 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
        (const FiniteElement<deal_II_dimension> &, FullMatrix<double> (&)[GeometryInfo<deal_II_dimension>::max_children_per_face],
         unsigned int, unsigned int);
 
-      template
-       void interpolate<deal_II_dimension>
-       (const hp::DoFHandler<deal_II_dimension> &, const Vector<double> &,
-        const hp::DoFHandler<deal_II_dimension> &, Vector<double> &);
-      template
-       void interpolate<deal_II_dimension>
-       (const hp::DoFHandler<deal_II_dimension> &, const Vector<double> &,
-        const hp::DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        Vector<double> &);
-      template
-       void interpolate<deal_II_dimension>
-       (const hp::DoFHandler<deal_II_dimension> &, const Vector<float> &,
-        const hp::DoFHandler<deal_II_dimension> &, Vector<float> &);
-      template
-       void interpolate<deal_II_dimension>
-       (const hp::DoFHandler<deal_II_dimension> &, const Vector<float> &,
-        const hp::DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        Vector<float> &);
-
 
       template FiniteElement<deal_II_dimension,deal_II_dimension> *
        get_fe_from_name<deal_II_dimension> (const std::string &);
@@ -213,47 +178,3 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 #endif
       \}
   }
-
-
-
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS; VEC : SERIAL_VECTORS)
-  {
-    namespace FETools
-      \{
-#if deal_II_dimension == deal_II_space_dimension
-     template
-       void back_interpolate<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const VEC &,
-        const FiniteElement<deal_II_dimension> &, VEC &);
-      template
-       void back_interpolate<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        const VEC &,
-        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        VEC &);
-      template
-       void interpolation_difference<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const VEC &,
-        const FiniteElement<deal_II_dimension> &, VEC &);
-      template
-       void interpolation_difference<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        const VEC &,
-        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        VEC &);
-      template
-       void project_dg<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const VEC &,
-        const DoFHandler<deal_II_dimension> &, VEC &);
-      template
-       void extrapolate<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const VEC &,
-        const DoFHandler<deal_II_dimension> &, VEC &);
-      template
-       void extrapolate<deal_II_dimension>
-       (const DoFHandler<deal_II_dimension> &, const VEC &,
-        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
-        VEC &);
-#endif
-      \}
-  }
diff --git a/deal.II/source/fe/fe_tools_interpolate.cc b/deal.II/source/fe/fe_tools_interpolate.cc
new file mode 100644 (file)
index 0000000..8eef0c9
--- /dev/null
@@ -0,0 +1,761 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2000 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/qprojector.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/block_vector.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
+#include <deal.II/lac/petsc_parallel_vector.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/petsc_parallel_block_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/fe/fe_tools.h>
+#include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/hp/dof_handler.h>
+
+#include <deal.II/base/std_cxx1x/shared_ptr.h>
+
+#include <deal.II/base/index_set.h>
+
+#include <iostream>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace FETools
+{
+  template <int dim, int spacedim,
+           template <int, int> class DH1,
+           template <int, int> class DH2,
+           class InVector, class OutVector>
+  void
+  interpolate(const DH1<dim, spacedim> &dof1,
+              const InVector           &u1,
+              const DH2<dim, spacedim> &dof2,
+              OutVector                &u2)
+  {
+    ConstraintMatrix dummy;
+    dummy.close();
+    interpolate(dof1, u1, dof2, dummy, u2);
+  }
+
+
+
+  template <int dim, int spacedim,
+           template <int, int> class DH1,
+           template <int, int> class DH2,
+           class InVector, class OutVector>
+  void
+  interpolate (const DH1<dim, spacedim> &dof1,
+               const InVector           &u1,
+               const DH2<dim, spacedim> &dof2,
+               const ConstraintMatrix   &constraints,
+               OutVector                &u2)
+  {
+    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
+
+    Assert(u1.size()==dof1.n_dofs(),
+           ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u2.size()==dof2.n_dofs(),
+           ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
+
+#ifdef DEAL_II_WITH_PETSC
+    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          // if u1 is a parallel distributed
+          // PETSc vector, we check the local
+          // size of u1 for safety
+          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+
+    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u2) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof2) != 0)
+        {
+          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size() == dof2.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size(), dof2.locally_owned_dofs().n_elements()));
+        };
+#endif
+    // allocate vectors at maximal
+    // size. will be reinited in inner
+    // cell, but Vector makes sure that
+    // this does not lead to
+    // reallocation of memory
+    Vector<typename OutVector::value_type> u1_local(DoFTools::max_dofs_per_cell(dof1));
+    Vector<typename OutVector::value_type> u2_local(DoFTools::max_dofs_per_cell(dof2));
+
+    // have a map for interpolation
+    // matrices. shared_ptr make sure
+    // that memory is released again
+    std::map<const FiniteElement<dim,spacedim> *,
+        std::map<const FiniteElement<dim,spacedim> *,
+        std_cxx1x::shared_ptr<FullMatrix<double> > > >
+        interpolation_matrices;
+
+    typename DH1<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active(),
+                                                     endc1 = dof1.end();
+    typename DH2<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active(),
+                                                     endc2 = dof2.end();
+
+    std::vector<types::global_dof_index> dofs;
+    dofs.reserve (DoFTools::max_dofs_per_cell (dof2));
+
+    u2 = 0;
+    OutVector touch_count(u2);
+    touch_count = 0;
+
+    // for distributed triangulations,
+    // we can only interpolate u1 on
+    // a cell, which this processor owns,
+    // so we have to know the subdomain_id
+    const types::subdomain_id subdomain_id =
+      dof1.get_tria().locally_owned_subdomain();
+
+    for (; cell1!=endc1; ++cell1, ++cell2)
+      if ((cell1->subdomain_id() == subdomain_id)
+          ||
+          (subdomain_id == numbers::invalid_subdomain_id))
+        {
+          Assert(cell1->get_fe().n_components() == cell2->get_fe().n_components(),
+                 ExcDimensionMismatch (cell1->get_fe().n_components(),
+                                       cell2->get_fe().n_components()));
+
+          // for continuous elements on
+          // grids with hanging nodes we
+          // need hanging node
+          // constraints. Consequentely,
+          // if there are no constraints
+          // then hanging nodes are not
+          // allowed.
+          const bool hanging_nodes_not_allowed
+            = ((cell2->get_fe().dofs_per_vertex != 0) &&
+               (constraints.n_constraints() == 0));
+
+          if (hanging_nodes_not_allowed)
+            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+              Assert (cell1->at_boundary(face) ||
+                      cell1->neighbor(face)->level() == cell1->level(),
+                      ExcHangingNodesNotAllowed(0));
+
+
+          const unsigned int dofs_per_cell1 = cell1->get_fe().dofs_per_cell;
+          const unsigned int dofs_per_cell2 = cell2->get_fe().dofs_per_cell;
+          u1_local.reinit (dofs_per_cell1);
+          u2_local.reinit (dofs_per_cell2);
+
+          // check if interpolation
+          // matrix for this particular
+          // pair of elements is already
+          // there
+          if (interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()].get() == 0)
+            {
+              std_cxx1x::shared_ptr<FullMatrix<double> >
+              interpolation_matrix (new FullMatrix<double> (dofs_per_cell2,
+                                                            dofs_per_cell1));
+              interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
+                = interpolation_matrix;
+
+              get_interpolation_matrix(cell1->get_fe(),
+                                       cell2->get_fe(),
+                                       *interpolation_matrix);
+            }
+
+          cell1->get_dof_values(u1, u1_local);
+          interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
+          ->vmult(u2_local, u1_local);
+
+          dofs.resize (dofs_per_cell2);
+          cell2->get_dof_indices(dofs);
+
+          for (unsigned int i=0; i<dofs_per_cell2; ++i)
+            {
+              u2(dofs[i])+=u2_local(i);
+              touch_count(dofs[i]) += 1;
+            }
+        }
+    // cell1 is at the end, so should
+    // be cell2
+    Assert (cell2 == endc2, ExcInternalError());
+
+    u2.compress(VectorOperation::add);
+    touch_count.compress(VectorOperation::add);
+
+    // if we work on parallel distributed
+    // vectors, we have to ensure, that we only
+    // work on dofs this processor owns.
+    IndexSet  locally_owned_dofs = dof2.locally_owned_dofs();
+
+    // when a discontinuous element is
+    // interpolated to a continuous
+    // one, we take the mean values.
+    // for parallel vectors check,
+    // if this component is owned by
+    // this processor.
+    for (types::global_dof_index i=0; i<dof2.n_dofs(); ++i)
+      if (locally_owned_dofs.is_element(i))
+        {
+          Assert(touch_count(i)!=0, ExcInternalError());
+          u2(i) /= touch_count(i);
+        }
+
+    // finish the work on parallel vectors
+    u2.compress(VectorOperation::insert);
+    // Apply hanging node constraints.
+    constraints.distribute(u2);
+  }
+
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void
+  back_interpolate(const DoFHandler<dim,spacedim>    &dof1,
+                   const InVector           &u1,
+                   const FiniteElement<dim,spacedim> &fe2,
+                   OutVector                &u1_interpolated)
+  {
+    Assert(dof1.get_fe().n_components() == fe2.n_components(),
+           ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
+    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u1_interpolated.size()==dof1.n_dofs(),
+           ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
+
+#ifdef DEAL_II_WITH_PETSC
+    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          // if u1 is a parallel distributed
+          // PETSc vector, we check the local
+          // size of u1 for safety
+          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+
+    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+#endif
+
+    // For continuous elements on grids
+    // with hanging nodes we need
+    // hanging node
+    // constraints. Consequently, when
+    // the elements are continuous no
+    // hanging node constraints are
+    // allowed.
+    const bool hanging_nodes_not_allowed=
+      (dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
+
+    const unsigned int dofs_per_cell1=dof1.get_fe().dofs_per_cell;
+
+    Vector<typename OutVector::value_type> u1_local(dofs_per_cell1);
+    Vector<typename OutVector::value_type> u1_int_local(dofs_per_cell1);
+
+    const types::subdomain_id subdomain_id =
+      dof1.get_tria().locally_owned_subdomain();
+
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
+                                                            endc = dof1.end();
+
+    FullMatrix<double> interpolation_matrix(dofs_per_cell1, dofs_per_cell1);
+    get_back_interpolation_matrix(dof1.get_fe(), fe2,
+                                  interpolation_matrix);
+    for (; cell!=endc; ++cell)
+      if ((cell->subdomain_id() == subdomain_id)
+          ||
+          (subdomain_id == numbers::invalid_subdomain_id))
+        {
+          if (hanging_nodes_not_allowed)
+            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+              Assert (cell->at_boundary(face) ||
+                      cell->neighbor(face)->level() == cell->level(),
+                      ExcHangingNodesNotAllowed(0));
+
+          cell->get_dof_values(u1, u1_local);
+          interpolation_matrix.vmult(u1_int_local, u1_local);
+          cell->set_dof_values(u1_int_local, u1_interpolated);
+        }
+
+    // if we work on a parallel PETSc vector
+    // we have to finish the work
+    u1_interpolated.compress(VectorOperation::insert);
+  }
+
+
+
+  template <int dim,
+           template <int> class DH,
+           class InVector, class OutVector, int spacedim>
+  void
+  back_interpolate(const DH<dim>            &dof1,
+                   const InVector           &u1,
+                   const FiniteElement<dim,spacedim> &fe2,
+                   OutVector                &u1_interpolated)
+  {
+    Assert(u1.size() == dof1.n_dofs(),
+           ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u1_interpolated.size() == dof1.n_dofs(),
+           ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
+
+#ifdef DEAL_II_WITH_PETSC
+    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          // if u1 is a parallel distributed
+          // PETSc vector, we check the local
+          // size of u1 for safety
+          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+
+    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+#endif
+
+    Vector<typename OutVector::value_type> u1_local(DoFTools::max_dofs_per_cell(dof1));
+    Vector<typename OutVector::value_type> u1_int_local(DoFTools::max_dofs_per_cell(dof1));
+
+    const types::subdomain_id subdomain_id =
+      dof1.get_tria().locally_owned_subdomain();
+
+    typename DH<dim>::active_cell_iterator cell = dof1.begin_active(),
+                                           endc = dof1.end();
+
+    // map from possible fe objects in
+    // dof1 to the back_interpolation
+    // matrices
+    std::map<const FiniteElement<dim> *,
+        std_cxx1x::shared_ptr<FullMatrix<double> > > interpolation_matrices;
+
+    for (; cell!=endc; ++cell)
+      if ((cell->subdomain_id() == subdomain_id)
+          ||
+          (subdomain_id == numbers::invalid_subdomain_id))
+        {
+          Assert(cell->get_fe().n_components() == fe2.n_components(),
+                 ExcDimensionMismatch(cell->get_fe().n_components(),
+                                      fe2.n_components()));
+
+          // For continuous elements on
+          // grids with hanging nodes we
+          // need hanging node
+          // constraints. Consequently,
+          // when the elements are
+          // continuous no hanging node
+          // constraints are allowed.
+          const bool hanging_nodes_not_allowed=
+            (cell->get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
+
+          if (hanging_nodes_not_allowed)
+            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+              Assert (cell->at_boundary(face) ||
+                      cell->neighbor(face)->level() == cell->level(),
+                      ExcHangingNodesNotAllowed(0));
+
+          const unsigned int dofs_per_cell1 = cell->get_fe().dofs_per_cell;
+
+          // make sure back_interpolation
+          // matrix is available
+          if (interpolation_matrices[&cell->get_fe()] != 0)
+            {
+              interpolation_matrices[&cell->get_fe()] =
+                std_cxx1x::shared_ptr<FullMatrix<double> >
+                (new FullMatrix<double>(dofs_per_cell1, dofs_per_cell1));
+              get_back_interpolation_matrix(dof1.get_fe(), fe2,
+                                            *interpolation_matrices[&cell->get_fe()]);
+            }
+
+          u1_local.reinit (dofs_per_cell1);
+          u1_int_local.reinit (dofs_per_cell1);
+
+          cell->get_dof_values(u1, u1_local);
+          interpolation_matrices[&cell->get_fe()]->vmult(u1_int_local, u1_local);
+          cell->set_dof_values(u1_int_local, u1_interpolated);
+        };
+
+    // if we work on a parallel PETSc vector
+    // we have to finish the work
+    u1_interpolated.compress(VectorOperation::insert);
+  }
+
+
+
+  namespace internal
+  {
+    namespace
+    {
+      template <int dim, int spacedim, class InVector>
+      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
+                             const ConstraintMatrix &constraints1,
+                             const InVector &u1,
+                             const DoFHandler<dim,spacedim> &dof2,
+                             const ConstraintMatrix &constraints2,
+                             InVector &u1_interpolated)
+      {
+        Vector<typename InVector::value_type> u2(dof2.n_dofs());
+        interpolate(dof1, u1, dof2, constraints2, u2);
+        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
+      }
+
+      // special version for PETSc
+#ifdef DEAL_II_WITH_PETSC
+      template <int dim, int spacedim>
+      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
+                             const ConstraintMatrix &constraints1,
+                             const PETScWrappers::MPI::Vector &u1,
+                             const DoFHandler<dim,spacedim> &dof2,
+                             const ConstraintMatrix &constraints2,
+                             PETScWrappers::MPI::Vector &u1_interpolated)
+      {
+        // if u1 is a parallel distributed PETSc vector, we create a
+        // vector u2 with based on the sets of locally owned and relevant
+        // dofs of dof2
+        IndexSet  dof2_locally_owned_dofs = dof2.locally_owned_dofs();
+        IndexSet  dof2_locally_relevant_dofs;
+        DoFTools::extract_locally_relevant_dofs (dof2,
+                                                 dof2_locally_relevant_dofs);
+
+        PETScWrappers::MPI::Vector  u2_out (u1.get_mpi_communicator(),
+                                            dof2_locally_owned_dofs);
+        interpolate(dof1, u1, dof2, constraints2, u2_out);
+        PETScWrappers::MPI::Vector  u2 (u1.get_mpi_communicator(),
+                                        dof2_locally_owned_dofs,
+                                        dof2_locally_relevant_dofs);
+        u2 = u2_out;
+        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
+      }
+#endif
+
+      // special version for parallel::distributed::Vector
+      template <int dim, int spacedim, typename Number>
+      void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
+                             const ConstraintMatrix &constraints1,
+                             const parallel::distributed::Vector<Number> &u1,
+                             const DoFHandler<dim,spacedim> &dof2,
+                             const ConstraintMatrix &constraints2,
+                             parallel::distributed::Vector<Number> &u1_interpolated)
+      {
+        IndexSet dof2_locally_owned_dofs = dof2.locally_owned_dofs();
+        IndexSet dof2_locally_relevant_dofs;
+        DoFTools::extract_locally_relevant_dofs (dof2,
+                                                 dof2_locally_relevant_dofs);
+
+        parallel::distributed::Vector<Number>
+        u2 (dof2_locally_owned_dofs,
+            dof2_locally_relevant_dofs,
+            u1.get_mpi_communicator());
+
+        interpolate(dof1, u1, dof2, constraints2, u2);
+        u2.update_ghost_values ();
+        interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
+      }
+    }
+  }
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void back_interpolate(const DoFHandler<dim,spacedim> &dof1,
+                        const ConstraintMatrix &constraints1,
+                        const InVector &u1,
+                        const DoFHandler<dim,spacedim> &dof2,
+                        const ConstraintMatrix &constraints2,
+                        OutVector &u1_interpolated)
+  {
+    // For discontinuous elements without constraints take the simpler version
+    // of the back_interpolate function.
+    if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
+        && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
+      back_interpolate(dof1, u1, dof2.get_fe(), u1_interpolated);
+    else
+      {
+        Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
+               ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+        Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+        Assert(u1_interpolated.size()==dof1.n_dofs(),
+               ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
+
+        // For continuous elements first interpolate to dof2, taking into
+        // account constraints2, and then interpolate back to dof1 taking into
+        // account constraints1
+        internal::back_interpolate(dof1, constraints1, u1, dof2, constraints2,
+                                   u1_interpolated);
+      }
+  }
+
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
+                                 const InVector &u1,
+                                 const FiniteElement<dim,spacedim> &fe2,
+                                 OutVector &u1_difference)
+  {
+    Assert(dof1.get_fe().n_components() == fe2.n_components(),
+           ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
+    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u1_difference.size()==dof1.n_dofs(),
+           ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs()));
+
+#ifdef DEAL_II_WITH_PETSC
+    if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          // if u1 is a parallel distributed
+          // PETSc vector, we check the local
+          // size of u1 for safety
+          Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+
+    if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference) != 0)
+      if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
+        {
+          Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size() == dof1.locally_owned_dofs().n_elements(),
+                 ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size(), dof1.locally_owned_dofs().n_elements()));
+        };
+#endif
+
+    // For continuous elements on grids
+    // with hanging nodes we need
+    // hanging node
+    // constraints. Consequently, when
+    // the elements are continuous no
+    // hanging node constraints are
+    // allowed.
+    const bool hanging_nodes_not_allowed=
+      (dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
+
+    const unsigned int dofs_per_cell=dof1.get_fe().dofs_per_cell;
+
+    Vector<typename OutVector::value_type> u1_local(dofs_per_cell);
+    Vector<typename OutVector::value_type> u1_diff_local(dofs_per_cell);
+
+    const types::subdomain_id subdomain_id =
+      dof1.get_tria().locally_owned_subdomain();
+
+    FullMatrix<double> difference_matrix(dofs_per_cell, dofs_per_cell);
+    get_interpolation_difference_matrix(dof1.get_fe(), fe2,
+                                        difference_matrix);
+
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
+                                                            endc = dof1.end();
+
+    for (; cell!=endc; ++cell)
+      if ((cell->subdomain_id() == subdomain_id)
+          ||
+          (subdomain_id == numbers::invalid_subdomain_id))
+        {
+          if (hanging_nodes_not_allowed)
+            for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+              Assert (cell->at_boundary(face) ||
+                      cell->neighbor(face)->level() == cell->level(),
+                      ExcHangingNodesNotAllowed(0));
+
+          cell->get_dof_values(u1, u1_local);
+          difference_matrix.vmult(u1_diff_local, u1_local);
+          cell->set_dof_values(u1_diff_local, u1_difference);
+        }
+
+    // if we work on a parallel PETSc vector
+    // we have to finish the work and
+    // update ghost values
+    u1_difference.compress(VectorOperation::insert);
+  }
+
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
+                                const ConstraintMatrix &constraints1,
+                                const InVector &u1,
+                                const DoFHandler<dim,spacedim> &dof2,
+                                const ConstraintMatrix &constraints2,
+                                OutVector &u1_difference)
+  {
+    // For discontinuous elements
+    // without constraints take the
+    // cheaper version of the
+    // interpolation_difference function.
+    if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
+        && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
+      interpolation_difference(dof1, u1, dof2.get_fe(), u1_difference);
+    else
+      {
+        back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
+        u1_difference.sadd(-1, u1);
+      }
+  }
+
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void project_dg(const DoFHandler<dim,spacedim> &dof1,
+                  const InVector &u1,
+                  const DoFHandler<dim,spacedim> &dof2,
+                  OutVector &u2)
+  {
+    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
+    Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
+           ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
+
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active();
+    typename DoFHandler<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active();
+    typename DoFHandler<dim,spacedim>::active_cell_iterator end = dof2.end();
+
+    const unsigned int n1 = dof1.get_fe().dofs_per_cell;
+    const unsigned int n2 = dof2.get_fe().dofs_per_cell;
+
+    Vector<double> u1_local(n1);
+    Vector<double> u2_local(n2);
+    std::vector<types::global_dof_index> dofs(n2);
+
+    FullMatrix<double> matrix(n2,n1);
+    get_projection_matrix(dof1.get_fe(), dof2.get_fe(), matrix);
+
+    while (cell2 != end)
+      {
+        cell1->get_dof_values(u1, u1_local);
+        matrix.vmult(u2_local, u1_local);
+        cell2->get_dof_indices(dofs);
+        for (unsigned int i=0; i<n2; ++i)
+          {
+            u2(dofs[i])+=u2_local(i);
+          }
+
+        ++cell1;
+        ++cell2;
+      }
+  }
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void extrapolate(const DoFHandler<dim,spacedim> &dof1,
+                   const InVector &u1,
+                   const DoFHandler<dim,spacedim> &dof2,
+                   OutVector &u2)
+  {
+    ConstraintMatrix dummy;
+    dummy.close();
+    extrapolate(dof1, u1, dof2, dummy, u2);
+  }
+
+
+
+  template <int dim, class InVector, class OutVector, int spacedim>
+  void extrapolate(const DoFHandler<dim,spacedim> &dof1,
+                   const InVector &u1,
+                   const DoFHandler<dim,spacedim> &dof2,
+                   const ConstraintMatrix &constraints,
+                   OutVector &u2)
+  {
+    Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
+           ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+    Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
+    Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+    Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
+
+    OutVector u3;
+    u3.reinit(u2);
+    interpolate(dof1, u1, dof2, constraints, u3);
+
+    const unsigned int dofs_per_cell  = dof2.get_fe().dofs_per_cell;
+    Vector<typename OutVector::value_type> dof_values(dofs_per_cell);
+
+    // make sure that each cell on the
+    // coarsest level is at least once
+    // refined. otherwise, we can't
+    // treat these cells and would
+    // generate a bogus result
+    {
+      typename DoFHandler<dim,spacedim>::cell_iterator cell = dof2.begin(0),
+                                                       endc = dof2.end(0);
+      for (; cell!=endc; ++cell)
+        Assert (cell->has_children(), ExcGridNotRefinedAtLeastOnce());
+    }
+
+    // then traverse grid bottom up
+    for (unsigned int level=0; level<dof1.get_tria().n_levels()-1; ++level)
+      {
+        typename DoFHandler<dim,spacedim>::cell_iterator cell=dof2.begin(level),
+                                                         endc=dof2.end(level);
+
+        for (; cell!=endc; ++cell)
+          if (!cell->active())
+            {
+              // check whether this
+              // cell has active
+              // children
+              bool active_children=false;
+              for (unsigned int child_n=0; child_n<cell->n_children(); ++child_n)
+                if (cell->child(child_n)->active())
+                  {
+                    active_children=true;
+                    break;
+                  }
+
+              // if there are active
+              // children, the we have
+              // to work on this
+              // cell. get the data
+              // from the one vector
+              // and set it on the
+              // other
+              if (active_children)
+                {
+                  cell->get_interpolated_dof_values(u3, dof_values);
+                  cell->set_dof_values_by_interpolation(dof_values, u2);
+                }
+            }
+      }
+
+    // Apply hanging node constraints.
+    constraints.distribute(u2);
+  }
+
+} // end of namespace FETools
+
+
+
+/*-------------- Explicit Instantiations -------------------------------*/
+#include "fe_tools_interpolate.inst"
+
+
+/*----------------------------   fe_tools.cc     ---------------------------*/
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/fe/fe_tools_interpolate.inst.in b/deal.II/source/fe/fe_tools_interpolate.inst.in
new file mode 100644 (file)
index 0000000..2c7fa67
--- /dev/null
@@ -0,0 +1,107 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS; Vector : SERIAL_VECTORS)
+  {
+    namespace FETools
+      \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template
+       void interpolate<deal_II_dimension,deal_II_space_dimension>
+       (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const Vector &,
+        const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, Vector &);
+
+      template
+       void interpolate<deal_II_dimension,deal_II_space_dimension>
+       (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const Vector &,
+        const DoFHandler<deal_II_dimension,deal_II_space_dimension> &, const ConstraintMatrix &,
+        Vector &);
+#endif
+      \}
+  }
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+    namespace FETools
+      \{
+#if deal_II_dimension == deal_II_space_dimension
+      template
+       void interpolate<deal_II_dimension>
+       (const hp::DoFHandler<deal_II_dimension> &, const Vector<double> &,
+        const hp::DoFHandler<deal_II_dimension> &, Vector<double> &);
+      template
+       void interpolate<deal_II_dimension>
+       (const hp::DoFHandler<deal_II_dimension> &, const Vector<double> &,
+        const hp::DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        Vector<double> &);
+      template
+       void interpolate<deal_II_dimension>
+       (const hp::DoFHandler<deal_II_dimension> &, const Vector<float> &,
+        const hp::DoFHandler<deal_II_dimension> &, Vector<float> &);
+      template
+       void interpolate<deal_II_dimension>
+       (const hp::DoFHandler<deal_II_dimension> &, const Vector<float> &,
+        const hp::DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        Vector<float> &);
+#endif
+      \}
+  }
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS; VEC : SERIAL_VECTORS)
+  {
+    namespace FETools
+      \{
+#if deal_II_dimension == deal_II_space_dimension
+     template
+       void back_interpolate<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const VEC &,
+        const FiniteElement<deal_II_dimension> &, VEC &);
+      template
+       void back_interpolate<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        const VEC &,
+        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        VEC &);
+      template
+       void interpolation_difference<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const VEC &,
+        const FiniteElement<deal_II_dimension> &, VEC &);
+      template
+       void interpolation_difference<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        const VEC &,
+        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        VEC &);
+      template
+       void project_dg<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const VEC &,
+        const DoFHandler<deal_II_dimension> &, VEC &);
+      template
+       void extrapolate<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const VEC &,
+        const DoFHandler<deal_II_dimension> &, VEC &);
+      template
+       void extrapolate<deal_II_dimension>
+       (const DoFHandler<deal_II_dimension> &, const VEC &,
+        const DoFHandler<deal_II_dimension> &, const ConstraintMatrix &,
+        VEC &);
+#endif
+      \}
+  }
index 1873d9c737122c81a3bb2dbdef839006b6dbf461..5a6115220a5fadf5960ce6d4fa60c5c5422872e6 100644 (file)
@@ -53,88 +53,46 @@ MappingC1<2>::add_line_support_points (const Triangulation<2>::cell_iterator &ce
   const unsigned int dim = 2;
   std::vector<Point<dim> > line_points (2);
 
-  // loop over each of the lines,
-  // and if it is at the
-  // boundary, then first get the
-  // boundary description and
-  // second compute the points on
-  // it. if not at the boundary,
-  // get the respective points
-  // from another function
+  // loop over each of the lines, and if it is at the boundary, then first get
+  // the boundary description and second compute the points on it. if not at
+  // the boundary, get the respective points from another function
   for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
     {
       const Triangulation<dim>::line_iterator line = cell->line(line_no);
 
       if (line->at_boundary())
         {
-          // first get the normal
-          // vectors at the two
-          // vertices of this line
-          // from the boundary
-          // description
+          // first get the normal vectors at the two vertices of this line
+          // from the boundary description
           const Boundary<dim> &boundary
             = line->get_triangulation().get_boundary(line->boundary_indicator());
 
           Boundary<dim>::FaceVertexNormals face_vertex_normals;
           boundary.get_normals_at_vertices (line, face_vertex_normals);
 
-          // then transform them into
-          // interpolation points for
-          // a cubic polynomial
+          // then transform them into interpolation points for a cubic
+          // polynomial
           //
-          // for this, note that if
-          // we describe the boundary
-          // curve as a polynomial in
-          // tangential coordinate
-          // @p{t=0..1} (along the
-          // line) and @p{s} in
-          // normal direction, then
-          // the cubic mapping is
-          // such that @p{s = a*t**3
-          // + b*t**2 + c*t + d}, and
-          // we want to determine the
-          // interpolation points at
-          // @p{t=1/3} and
-          // @p{t=2/3}. Since at
-          // @p{t=0,1} we want a
-          // vertex which is actually
-          // at the boundary, we know
-          // that @p{d=0} and
-          // @p{a=-b-c}. As
-          // side-conditions, we want
-          // that the derivatives at
-          // @p{t=0} and @p{t=1},
-          // i.e. at the vertices
-          // match those returned by
-          // the boundary. We then
-          // have that
-          // @p{s(1/3)=1/27(2b+8c)}
-          // and
-          // @p{s(2/3)=4/27b+10/27c}.
+          // for this, note that if we describe the boundary curve as a
+          // polynomial in tangential coordinate @p{t=0..1} (along the line)
+          // and @p{s} in normal direction, then the cubic mapping is such
+          // that @p{s = a*t**3 + b*t**2 + c*t + d}, and we want to determine
+          // the interpolation points at @p{t=0.276} and @p{t=0.724}
+          // (Gauss-Lobatto points). Since at @p{t=0,1} we want a vertex which
+          // is actually at the boundary, we know that @p{d=0} and @p{a=-b-c},
+          // which gives @p{s(0.276)} and @{s(0.726)} in terms of @p{b,c}. As
+          // side-conditions, we want that the derivatives at @p{t=0} and
+          // @p{t=1}, i.e. at the vertices match those returned by the
+          // boundary.
           //
-          // The task is then first
-          // to determine the
-          // coefficients from the
-          // tangentials. for that,
-          // first rotate the
-          // tangents of @p{s(t)}
-          // into the global
-          // coordinate system. they
-          // are @p{A (1,c)} and @p{A
-          // (1,-b-2c)} with @p{A} the
-          // rotation matrix, since
-          // the tangentials in the
-          // coordinate system
-          // relative to the line are
-          // @p{(1,c)} and @p{(1,-b-2c)}
-          // at the two vertices,
-          // respectively. We then
-          // have to make sure by
-          // matching @p{b,c} that
-          // these tangentials are
-          // orthogonal to the normals
-          // returned by the boundary
-          // object
+          // The task is then first to determine the coefficients from the
+          // tangentials. for that, first rotate the tangents of @p{s(t)} into
+          // the global coordinate system. they are @p{A (1,c)} and @p{A
+          // (1,-b-2c)} with @p{A} the rotation matrix, since the tangentials
+          // in the coordinate system relative to the line are @p{(1,c)} and
+          // @p{(1,-b-2c)} at the two vertices, respectively. We then have to
+          // make sure by matching @p{b,c} that these tangentials are
+          // orthogonal to the normals returned by the boundary object
           const Tensor<1,2> coordinate_vector = line->vertex(1) - line->vertex(0);
           const double      h                 = std::sqrt(coordinate_vector * coordinate_vector);
           Tensor<1,2> coordinate_axis = coordinate_vector;
@@ -151,18 +109,18 @@ MappingC1<2>::add_line_support_points (const Triangulation<2>::cell_iterator &ce
                              -face_vertex_normals[1][0] * std::sin(alpha)))
                            -2*c;
 
+          QGaussLobatto<1> quad_points(4);
+          const double t1 = quad_points.point(1)[0];
+          const double t2 = quad_points.point(2)[0];
+          const double s_t1 = (((-b-c)*t1+b)*t1+c)*t1;
+          const double s_t2 = (((-b-c)*t2+b)*t2+c)*t2;
 
-          // next evaluate the so
-          // determined cubic
-          // polynomial at the points
-          // 1/3 and 2/3, first in
-          // unit coordinates
-          const Point<2> new_unit_points[2] = { Point<2>(1./3., 1./27.*(2*b+8*c)),
-                                                Point<2>(2./3., 4./27.*b+10./27.*c)
+          // next evaluate the so determined cubic polynomial at the points
+          // 1/3 and 2/3, first in unit coordinates
+          const Point<2> new_unit_points[2] = { Point<2>(t1, s_t1),
+                                                Point<2>(t2, s_t2)
                                               };
-          // then transform these
-          // points to real
-          // coordinates by rotating,
+          // then transform these points to real coordinates by rotating,
           // scaling and shifting
           for (unsigned int i=0; i<2; ++i)
             {
index 18cb2b111045fd59d847b1ffcd54f81ffe349603..4ee1d4374c86afca511c663c7f6ffba075b4554d 100644 (file)
@@ -130,15 +130,11 @@ MappingQ<dim,spacedim>::MappingQ (const unsigned int p,
                               || (dim != spacedim)),
   feq(degree)
 {
-  // Construct the tensor product
-  // polynomials used as shape
-  // functions for the Qp mapping of
-  // cells at the boundary.
-  std::vector<Polynomials::LagrangeEquidistant> v;
-  for (unsigned int i=0; i<=degree; ++i)
-    v.push_back(Polynomials::LagrangeEquidistant(degree,i));
-
-  tensor_pols = new TensorProductPolynomials<dim> (v);
+  // Construct the tensor product polynomials used as shape functions for the
+  // Qp mapping of cells at the boundary.
+  const QGaussLobatto<1> points(degree+1);
+  tensor_pols = new TensorProductPolynomials<dim>
+    (Polynomials::generate_complete_Lagrange_basis(points.get_points()));
   Assert (n_shape_functions==tensor_pols->n(),
           ExcInternalError());
   Assert(n_inner+n_outer==n_shape_functions, ExcInternalError());
@@ -294,10 +290,8 @@ MappingQ<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
 }
 
 
-// Note that the CellSimilarity flag is
-// modifyable, since MappingQ can need to
-// recalculate data even when cells are
-// similar.
+// Note that the CellSimilarity flag is modifyable, since MappingQ can need to
+// recalculate data even when cells are similar.
 template<int dim, int spacedim>
 void
 MappingQ<dim,spacedim>::fill_fe_values (
@@ -312,35 +306,23 @@ MappingQ<dim,spacedim>::fill_fe_values (
   std::vector<Point<spacedim> >                             &normal_vectors,
   CellSimilarity::Similarity                           &cell_similarity) const
 {
-  // convert data object to internal
-  // data for this class. fails with
-  // an exception if that is not
-  // possible
+  // convert data object to internal data for this class. fails with an
+  // exception if that is not possible
   Assert (dynamic_cast<InternalData *> (&mapping_data) != 0, ExcInternalError());
   InternalData &data = static_cast<InternalData &> (mapping_data);
 
-  // check whether this cell needs
-  // the full mapping or can be
-  // treated by a reduced Q1 mapping,
-  // e.g. if the cell is in the
-  // interior of the domain
+  // check whether this cell needs the full mapping or can be treated by a
+  // reduced Q1 mapping, e.g. if the cell is in the interior of the domain
   data.use_mapping_q1_on_current_cell = !(use_mapping_q_on_all_cells
                                           || cell->has_boundary_lines());
 
-  // depending on this result, use this or
-  // the other data object for the
-  // mapping. furthermore, we need to
-  // ensure that the flag indicating
-  // whether we can use some similarity has
-  // to be modified - for a general
-  // MappingQ, the data needs to be
-  // recomputed anyway since then the
-  // mapping changes the data. this needs
-  // to be known also for later operations,
-  // so modify the variable here. this also
-  // affects the calculation of the next
-  // cell -- if we use Q1 data on the next
-  // cell, the data will still be invalid.
+  // depending on this result, use this or the other data object for the
+  // mapping. furthermore, we need to ensure that the flag indicating whether
+  // we can use some similarity has to be modified - for a general MappingQ,
+  // the data needs to be recomputed anyway since then the mapping changes the
+  // data. this needs to be known also for later operations, so modify the
+  // variable here. this also affects the calculation of the next cell -- if
+  // we use Q1 data on the next cell, the data will still be invalid.
   typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
@@ -372,34 +354,23 @@ MappingQ<dim,spacedim>::fill_fe_face_values (
   std::vector<Tensor<1,spacedim> >  &exterior_forms,
   std::vector<Point<spacedim> >     &normal_vectors) const
 {
-  // convert data object to internal
-  // data for this class. fails with
-  // an exception if that is not
-  // possible
+  // convert data object to internal data for this class. fails with an
+  // exception if that is not possible
   Assert (dynamic_cast<InternalData *> (&mapping_data) != 0,
           ExcInternalError());
   InternalData &data = static_cast<InternalData &> (mapping_data);
 
-  // check whether this cell needs
-  // the full mapping or can be
-  // treated by a reduced Q1 mapping,
-  // e.g. if the cell is entirely in
-  // the interior of the domain. note
-  // that it is not sufficient to ask
-  // whether the present _face_ is in
-  // the interior, as the mapping on
-  // the face depends on the mapping
-  // of the cell, which in turn
-  // depends on the fact whether
-  // _any_ of the faces of this cell
-  // is at the boundary, not only the
-  // present face
+  // check whether this cell needs the full mapping or can be treated by a
+  // reduced Q1 mapping, e.g. if the cell is entirely in the interior of the
+  // domain. note that it is not sufficient to ask whether the present _face_
+  // is in the interior, as the mapping on the face depends on the mapping of
+  // the cell, which in turn depends on the fact whether _any_ of the faces of
+  // this cell is at the boundary, not only the present face
   data.use_mapping_q1_on_current_cell=!(use_mapping_q_on_all_cells
                                         || cell->has_boundary_lines());
 
-  // depending on this result, use
-  // this or the other data object
-  // for the mapping
+  // depending on this result, use this or the other data object for the
+  // mapping
   typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
@@ -434,34 +405,23 @@ MappingQ<dim,spacedim>::fill_fe_subface_values (const typename Triangulation<dim
                                                 std::vector<Tensor<1,spacedim> >  &exterior_forms,
                                                 std::vector<Point<spacedim> >     &normal_vectors) const
 {
-  // convert data object to internal
-  // data for this class. fails with
-  // an exception if that is not
-  // possible
+  // convert data object to internal data for this class. fails with an
+  // exception if that is not possible
   Assert (dynamic_cast<InternalData *> (&mapping_data) != 0,
           ExcInternalError());
   InternalData &data = static_cast<InternalData &> (mapping_data);
 
-  // check whether this cell needs
-  // the full mapping or can be
-  // treated by a reduced Q1 mapping,
-  // e.g. if the cell is entirely in
-  // the interior of the domain. note
-  // that it is not sufficient to ask
-  // whether the present _face_ is in
-  // the interior, as the mapping on
-  // the face depends on the mapping
-  // of the cell, which in turn
-  // depends on the fact whether
-  // _any_ of the faces of this cell
-  // is at the boundary, not only the
-  // present face
+  // check whether this cell needs the full mapping or can be treated by a
+  // reduced Q1 mapping, e.g. if the cell is entirely in the interior of the
+  // domain. note that it is not sufficient to ask whether the present _face_
+  // is in the interior, as the mapping on the face depends on the mapping of
+  // the cell, which in turn depends on the fact whether _any_ of the faces of
+  // this cell is at the boundary, not only the present face
   data.use_mapping_q1_on_current_cell=!(use_mapping_q_on_all_cells
                                         || cell->has_boundary_lines());
 
-  // depending on this result, use
-  // this or the other data object
-  // for the mapping
+  // depending on this result, use this or the other data object for the
+  // mapping
   typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
   if (data.use_mapping_q1_on_current_cell)
     p_data=&data.mapping_q1_data;
@@ -503,25 +463,19 @@ MappingQ<dim,spacedim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
   const unsigned int n_inner_2d=(degree-1)*(degree-1);
   const unsigned int n_outer_2d=4+4*(degree-1);
 
-  // first check whether we have precomputed
-  // the values for some polynomial degree;
-  // the sizes of arrays is
-  // n_inner_2d*n_outer_2d
+  // first check whether we have precomputed the values for some polynomial
+  // degree; the sizes of arrays is n_inner_2d*n_outer_2d
   double const *loqv_ptr=0;
   switch (degree)
     {
-      // for degree==1, we shouldn't have to
-      // compute any support points, since
+      // for degree==1, we shouldn't have to compute any support points, since
       // all of them are on the vertices
 
     case 2:
     {
-      // (checked these values against the
-      // output of compute_laplace_vector
-      // again, and found they're indeed
-      // right -- just in case someone
-      // wonders where they come from --
-      // WB)
+      // (checked these values against the output of compute_laplace_vector
+      // again, and found they're indeed right -- just in case someone wonders
+      // where they come from -- WB)
       static const double loqv2[1*8]
         = {1/16., 1/16., 1/16., 1/16., 3/16., 3/16., 3/16., 3/16.};
       loqv_ptr=&loqv2[0];
@@ -532,133 +486,14 @@ MappingQ<dim,spacedim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
       break;
     }
 
-    case 3:
-    {
-      // (same as above)
-      static const double loqv3[4*12]
-        = {80/1053., 1/81., 1/81., 11/1053., 25/117., 44/351.,
-           7/117., 16/351., 25/117., 44/351., 7/117., 16/351.,
-           1/81., 80/1053., 11/1053., 1/81., 7/117., 16/351.,
-           25/117., 44/351., 44/351., 25/117., 16/351., 7/117.,
-           1/81., 11/1053., 80/1053., 1/81., 44/351., 25/117.,
-           16/351., 7/117., 7/117., 16/351., 25/117., 44/351.,
-           11/1053., 1/81., 1/81., 80/1053., 16/351., 7/117.,
-           44/351., 25/117., 16/351., 7/117., 44/351., 25/117.
-          };
-      Assert (sizeof(loqv3)/sizeof(loqv3[0]) ==
-              n_inner_2d * n_outer_2d,
-              ExcInternalError());
-
-      loqv_ptr=&loqv3[0];
-
-      break;
-    }
-
-
-    case 4:
-    {
-      static const double loqv4[9*16]
-        = {0.07405921850311571, -0.001075744628905992,
-           -0.001075744628906007, 0.001914292239071463,
-           0.2231273865431892, 0.1346851306015187,
-           0.03812914216116724, 0.02913160002633252,
-           0.02200737428129396, 0.01600835564431224,
-           0.2231273865431891, 0.1346851306015187,
-           0.03812914216116723, 0.02913160002633253,
-           0.02200737428129391, 0.01600835564431222,
-
-           0.00664803151334206, 0.006648031513342719,
-           0.002873452861657458, 0.002873452861657626,
-           0.07903572682584378, 0.05969238281250031,
-           0.03619864817415824, 0.07903572682584187,
-           0.0596923828124999, 0.03619864817415815,
-           0.1527716818820237, 0.2348152760709273,
-           0.152771681882024, 0.02496269311797778,
-           0.04081948955407129, 0.02496269311797789,
-
-           -0.001075744628906923, 0.07405921850311589,
-           0.001914292239071339, -0.001075744628905884,
-           0.02913160002633509, 0.02200737428129395,
-           0.01600835564431229, 0.2231273865431878,
-           0.1346851306015183, 0.0381291421611672,
-           0.03812914216116729, 0.1346851306015185,
-           0.2231273865431898, 0.01600835564431217,
-           0.02200737428129394, 0.02913160002633262,
-
-           0.006648031513342073, 0.002873452861657473,
-           0.006648031513342726, 0.002873452861657636,
-           0.1527716818820238, 0.2348152760709273,
-           0.152771681882024, 0.02496269311797779,
-           0.04081948955407131, 0.0249626931179779,
-           0.07903572682584376, 0.05969238281250026,
-           0.03619864817415824, 0.07903572682584187,
-           0.0596923828124998, 0.0361986481741581,
-
-           0.01106770833333302, 0.01106770833333336,
-           0.01106770833333337, 0.01106770833333374,
-           0.06770833333333424, 0.1035156250000011,
-           0.0677083333333344, 0.06770833333333376,
-           0.103515624999999, 0.06770833333333399,
-           0.06770833333333422, 0.1035156250000009,
-           0.06770833333333436, 0.0677083333333337,
-           0.1035156249999988, 0.0677083333333339,
-
-           0.002873452861657185, 0.006648031513342362,
-           0.002873452861657334, 0.006648031513343038,
-           0.02496269311797779, 0.04081948955407401,
-           0.02496269311797788, 0.1527716818820234,
-           0.234815276070926, 0.1527716818820237,
-           0.03619864817415819, 0.05969238281250028,
-           0.07903572682584407, 0.03619864817415804,
-           0.05969238281249986, 0.0790357268258422,
-
-           -0.001075744628906913, 0.00191429223907134,
-           0.07405921850311592, -0.001075744628905865,
-           0.03812914216116729, 0.1346851306015185,
-           0.2231273865431899, 0.01600835564431217,
-           0.02200737428129396, 0.02913160002633264,
-           0.02913160002633509, 0.02200737428129391,
-           0.01600835564431228, 0.2231273865431878,
-           0.1346851306015183, 0.03812914216116718,
-
-           0.002873452861657176, 0.002873452861657321,
-           0.006648031513342374, 0.006648031513343037,
-           0.03619864817415817, 0.05969238281250032,
-           0.07903572682584409, 0.03619864817415805,
-           0.05969238281249992, 0.07903572682584221,
-           0.02496269311797776, 0.04081948955407392,
-           0.02496269311797785, 0.1527716818820233,
-           0.2348152760709258, 0.1527716818820236,
-
-           0.001914292239071237, -0.001075744628906803,
-           -0.001075744628906778, 0.07405921850311617,
-           0.01600835564431228, 0.02200737428129401,
-           0.02913160002633524, 0.03812914216116726,
-           0.1346851306015182, 0.2231273865431886,
-           0.01600835564431228, 0.02200737428129397,
-           0.02913160002633523, 0.03812914216116726,
-           0.1346851306015181, 0.2231273865431886,
-          };
-
-      Assert (sizeof(loqv4)/sizeof(loqv4[0]) ==
-              n_inner_2d * n_outer_2d,
-              ExcInternalError());
-
-      loqv_ptr=&loqv4[0];
-
-      break;
-    }
-
-    // no other cases implemented,
-    // so simply fall through
+    // no other cases implemented, so simply fall through
     default:
       break;
     }
 
   if (loqv_ptr!=0)
     {
-      // precomputed. copy values to
-      // the loqvs array
+      // precomputed. copy values to the loqvs array
       loqvs.reinit(n_inner_2d, n_outer_2d);
       for (unsigned int unit_point=0; unit_point<n_inner_2d; ++unit_point)
         for (unsigned int k=0; k<n_outer_2d; ++k)
@@ -667,36 +502,20 @@ MappingQ<dim,spacedim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
   else
     {
       // not precomputed, then do so now
-      if (dim==2)
+      if (dim == 2)
         compute_laplace_vector(loqvs);
-      else
-        // computing the Laplace vector for
-        // faces is not supported in 3d at
-        // present. presumably, doing so
-        // would not be so hard: we would
-        // only have to call the function in
-        // 2d, i.e. the quad(=face) values in
-        // 3d are equal to the quad(=cell)
-        // values in 2d. however, that would
-        // require us to link in the 2d
-        // library, which is kind of awkward
-        // (note that compute_laplace_vector
-        // really makes use of a lot of 2d
-        // stuff, such as FEValues etc). an
-        // alternative would be to precompute
-        // the values of this array for a
-        // couple of higher mapping orders,
-        // pin down their values and insert
-        // them into the array above.
-        Assert (false, ExcNotImplemented());
+      else if (dim == 3)
+        {
+          MappingQ<2,2> mapping_2d(this->degree);
+          loqvs = mapping_2d.laplace_on_quad_vector;
+        }
     }
 
-  // the sum of weights of the points
-  // at the outer rim should be
-  // one. check this
+  // the sum of weights of the points at the outer rim should be one. check
+  // this
   for (unsigned int unit_point=0; unit_point<loqvs.n_rows(); ++unit_point)
     Assert(std::fabs(std::accumulate(loqvs[unit_point].begin(),
-                                     loqvs[unit_point].end(),0.)-1)<1e-12*this->degree*this->degree,
+                                     loqvs[unit_point].end(),0.)-1)<1e-13*this->degree,
            ExcInternalError());
 }
 
@@ -708,9 +527,8 @@ MappingQ<3>::set_laplace_on_hex_vector(Table<2,double> &lohvs) const
 {
   Assert(degree>1, ExcInternalError());
 
-  // first check whether we have
-  // precomputed the values for some
-  // polynomial degree
+  // first check whether we have precomputed the values for some polynomial
+  // degree
   double const *lohv_ptr=0;
   if (degree==2)
     {
@@ -726,8 +544,7 @@ MappingQ<3>::set_laplace_on_hex_vector(Table<2,double> &lohvs) const
 
   if (lohv_ptr!=0)
     {
-      // precomputed. copy values to
-      // the lohvs array
+      // precomputed. copy values to the lohvs array
       lohvs.reinit(n_inner, n_outer);
       for (unsigned int unit_point=0; unit_point<n_inner; ++unit_point)
         for (unsigned int k=0; k<n_outer; ++k)
@@ -737,12 +554,11 @@ MappingQ<3>::set_laplace_on_hex_vector(Table<2,double> &lohvs) const
     // not precomputed, then do so now
     compute_laplace_vector(lohvs);
 
-  // the sum of weights of the points
-  // at the outer rim should be
-  // one. check this
+  // the sum of weights of the points at the outer rim should be one. check
+  // this
   for (unsigned int unit_point=0; unit_point<n_inner; ++unit_point)
     Assert(std::fabs(std::accumulate(lohvs[unit_point].begin(),
-                                     lohvs[unit_point].end(),0.) - 1)<1e-13,
+                                     lohvs[unit_point].end(),0.) - 1)<1e-12*this->degree*this->degree,
            ExcInternalError());
 }
 
@@ -773,14 +589,11 @@ MappingQ<dim,spacedim>::compute_laplace_vector(Table<2,double> &lvs) const
   Assert(lvs.n_rows()==0, ExcInternalError());
   Assert(dim==2 || dim==3, ExcNotImplemented());
 
-  // for degree==1, we shouldn't have to
-  // compute any support points, since all of
-  // them are on the vertices
+  // for degree==1, we shouldn't have to compute any support points, since all
+  // of them are on the vertices
   Assert(degree>1, ExcInternalError());
 
-  // compute the shape
-  // gradients at the quadrature
-  // points on the unit cell
+  // compute the shape gradients at the quadrature points on the unit cell
   const QGauss<dim> quadrature(degree+1);
   const unsigned int n_q_points=quadrature.size();
 
@@ -788,37 +601,44 @@ MappingQ<dim,spacedim>::compute_laplace_vector(Table<2,double> &lvs) const
   quadrature_data.shape_derivatives.resize(n_shape_functions * n_q_points);
   this->compute_shapes(quadrature.get_points(), quadrature_data);
 
-  // Compute the stiffness matrix of
-  // the inner dofs
-  FullMatrix<double> S(n_inner);
+  // Compute the stiffness matrix of the inner dofs
+  FullMatrix<long double> S(n_inner);
   for (unsigned int point=0; point<n_q_points; ++point)
     for (unsigned int i=0; i<n_inner; ++i)
       for (unsigned int j=0; j<n_inner; ++j)
-        S(i,j) += contract(quadrature_data.derivative(point, n_outer+i),
-                           quadrature_data.derivative(point, n_outer+j))
-                  * quadrature.weight(point);
+       {
+         long double res = 0.;
+         for (unsigned int l=0; l<dim; ++l)
+           res += (long double)quadrature_data.derivative(point, n_outer+i)[l] *
+                  (long double)quadrature_data.derivative(point, n_outer+j)[l];
 
-  // Compute the components of T to be the
-  // product of gradients of inner and
+         S(i,j) += res * (long double)quadrature.weight(point);
+       }
+
+  // Compute the components of T to be the product of gradients of inner and
   // outer shape functions.
-  FullMatrix<double> T(n_inner, n_outer);
+  FullMatrix<long double> T(n_inner, n_outer);
   for (unsigned int point=0; point<n_q_points; ++point)
     for (unsigned int i=0; i<n_inner; ++i)
       for (unsigned int k=0; k<n_outer; ++k)
-        T(i,k) += contract(quadrature_data.derivative(point, n_outer+i),
-                           quadrature_data.derivative(point, k))
-                  *quadrature.weight(point);
+       {
+         long double res = 0.;
+         for (unsigned int l=0; l<dim; ++l)
+           res += (long double)quadrature_data.derivative(point, n_outer+i)[l] *
+                  (long double)quadrature_data.derivative(point, k)[l];
+
+         T(i,k) += res *(long double)quadrature.weight(point);
+       }
 
-  FullMatrix<double> S_1(n_inner);
+  FullMatrix<long double> S_1(n_inner);
   S_1.invert(S);
 
-  FullMatrix<double> S_1_T(n_inner, n_outer);
+  FullMatrix<long double> S_1_T(n_inner, n_outer);
 
   // S:=S_1*T
   S_1.mmult(S_1_T,T);
 
-  // Resize and initialize the
-  // lvs
+  // Resize and initialize the lvs
   lvs.reinit (n_inner, n_outer);
   for (unsigned int i=0; i<n_inner; ++i)
     for (unsigned int k=0; k<n_outer; ++k)
@@ -832,16 +652,10 @@ void
 MappingQ<dim,spacedim>::apply_laplace_vector(const Table<2,double> &lvs,
                                              std::vector<Point<spacedim> > &a) const
 {
-  // check whether the data we need
-  // is really available. if you fail
-  // here and if
-  // lvs==laplace_on_quad_vector in
-  // the calling function, then we
-  // didn't compute the quad laplace
-  // vector. this is mentioned in the
-  // constructor of this class,
-  // although I don't understand the
-  // reason for not aborting there
+  // check whether the data we need is really available. if you fail here and
+  // if lvs==laplace_on_quad_vector in the calling function, then we didn't
+  // compute the quad laplace vector. this is mentioned in the constructor of
+  // this class, although I don't understand the reason for not aborting there
   // any more [WB]
   Assert(lvs.n_rows()!=0, ExcLaplaceVectorNotSet(degree));
 
@@ -852,12 +666,9 @@ MappingQ<dim,spacedim>::apply_laplace_vector(const Table<2,double> &lvs,
   Assert(a.size()==n_outer_apply,
          ExcDimensionMismatch(a.size(), n_outer_apply));
 
-  // compute each inner point as
-  // linear combination of the outer
-  // points. the weights are given by
-  // the lvs entries, the outer
-  // points are the first (existing)
-  // elements of a
+  // compute each inner point as linear combination of the outer points. the
+  // weights are given by the lvs entries, the outer points are the first
+  // (existing) elements of a
   for (unsigned int unit_point=0; unit_point<n_inner_apply; ++unit_point)
     {
       Assert(lvs.n_cols()==n_outer_apply, ExcInternalError());
@@ -876,18 +687,13 @@ MappingQ<dim,spacedim>::compute_mapping_support_points(
   const typename Triangulation<dim,spacedim>::cell_iterator &cell,
   std::vector<Point<spacedim> > &a) const
 {
-  // if this is a cell for which we
-  // want to compute the full
-  // mapping, then get them from the
-  // following function
+  // if this is a cell for which we want to compute the full mapping, then get
+  // them from the following function
   if (use_mapping_q_on_all_cells || cell->has_boundary_lines())
     compute_support_points_laplace(cell, a);
   else
-    // otherwise: use a Q1 mapping
-    // for which the mapping shape
-    // function support points are
-    // simply the vertices of the
-    // cell
+    // otherwise: use a Q1 mapping for which the mapping shape function
+    // support points are simply the vertices of the cell
     {
       a.resize(GeometryInfo<dim>::vertices_per_cell);
 
@@ -902,8 +708,7 @@ void
 MappingQ<dim,spacedim>::compute_support_points_laplace(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                                                        std::vector<Point<spacedim> > &a) const
 {
-  // in any case, we need the
-  // vertices first
+  // in any case, we need the vertices first
   a.resize(GeometryInfo<dim>::vertices_per_cell);
   for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
     a[i] = cell->vertex(i);
@@ -915,11 +720,8 @@ MappingQ<dim,spacedim>::compute_support_points_laplace(const typename Triangulat
         add_line_support_points(cell, a);
         break;
       case 2:
-        // in 2d, add the
-        // points on the four
-        // bounding lines to
-        // the exterior (outer)
-        // points
+        // in 2d, add the points on the four bounding lines to the exterior
+        // (outer) points
         add_line_support_points (cell, a);
         if (dim != spacedim)
           add_quad_support_points(cell, a);
@@ -929,9 +731,7 @@ MappingQ<dim,spacedim>::compute_support_points_laplace(const typename Triangulat
 
       case 3:
       {
-        // in 3d also add the
-        // points located on
-        // the boundary faces
+        // in 3d also add the points located on the boundary faces
         add_line_support_points (cell, a);
         add_quad_support_points (cell, a);
         apply_laplace_vector (laplace_on_hex_vector, a);
@@ -950,8 +750,7 @@ void
 MappingQ<1>::add_line_support_points (const Triangulation<1>::cell_iterator &,
                                       std::vector<Point<1> > &) const
 {
-  // there are no points on bounding
-  // lines which are to be added
+  // there are no points on bounding lines which are to be added
   const unsigned int dim=1;
   Assert (dim > 1, ExcImpossibleInDim(dim));
 }
@@ -965,8 +764,7 @@ MappingQ<1,2>::add_line_support_points (const Triangulation<1,2>::cell_iterator
 {
   const unsigned int dim      = 1;
   const unsigned int spacedim = 2;
-  // Ask for the mid point, if that's
-  // the only thing we need.
+  // Ask for the mid point, if that's the only thing we need.
   if (degree==2)
     {
       const Boundary<dim,spacedim> *const boundary
@@ -974,10 +772,8 @@ MappingQ<1,2>::add_line_support_points (const Triangulation<1,2>::cell_iterator
       a.push_back(boundary->get_new_point_on_line(cell));
     }
   else
-    // otherwise call the more
-    // complicated functions and ask
-    // for inner points from the
-    // boundary description
+    // otherwise call the more complicated functions and ask for inner points
+    // from the boundary description
     {
       std::vector<Point<spacedim> > line_points (degree-1);
 
@@ -999,8 +795,7 @@ MappingQ<1,3>::add_line_support_points (const Triangulation<1,3>::cell_iterator
 {
   const unsigned int dim      = 1;
   const unsigned int spacedim = 3;
-  // Ask for the mid point, if that's
-  // the only thing we need.
+  // Ask for the mid point, if that's the only thing we need.
   if (degree==2)
     {
       const Boundary<dim,spacedim> *const boundary
@@ -1008,10 +803,8 @@ MappingQ<1,3>::add_line_support_points (const Triangulation<1,3>::cell_iterator
       a.push_back(boundary->get_new_point_on_line(cell));
     }
   else
-    // otherwise call the more
-    // complicated functions and ask
-    // for inner points from the
-    // boundary description
+    // otherwise call the more complicated functions and ask for inner points
+    // from the boundary description
     {
       std::vector<Point<spacedim> > line_points (degree-1);
 
@@ -1032,8 +825,7 @@ MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<di
                                                  std::vector<Point<spacedim> > &a) const
 {
   static const StraightBoundary<dim,spacedim> straight_boundary;
-  // if we only need the midpoint,
-  // then ask for it.
+  // if we only need the midpoint, then ask for it.
   if (degree==2)
     {
       for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
@@ -1050,19 +842,13 @@ MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<di
         };
     }
   else
-    // otherwise call the more
-    // complicated functions and ask
-    // for inner points from the
-    // boundary description
+    // otherwise call the more complicated functions and ask for inner points
+    // from the boundary description
     {
       std::vector<Point<spacedim> > line_points (degree-1);
 
-      // loop over each of the lines,
-      // and if it is at the
-      // boundary, then first get the
-      // boundary description and
-      // second compute the points on
-      // it
+      // loop over each of the lines, and if it is at the boundary, then first
+      // get the boundary description and second compute the points on it
       for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
         {
           const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
@@ -1077,8 +863,7 @@ MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<di
           boundary->get_intermediate_points_on_line (line, line_points);
           if (dim==3)
             {
-              // in 3D, lines might be in wrong
-              // orientation. if so, reverse
+              // in 3D, lines might be in wrong orientation. if so, reverse
               // the vector
               if (cell->line_orientation(line_no))
                 a.insert (a.end(), line_points.begin(), line_points.end());
@@ -1086,9 +871,8 @@ MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<di
                 a.insert (a.end(), line_points.rbegin(), line_points.rend());
             }
           else
-            // in 2D, lines always have the
-            // correct orientation. simply
-            // append all points
+            // in 2D, lines always have the correct orientation. simply append
+            // all points
             a.insert (a.end(), line_points.begin(), line_points.end());
 
         }
@@ -1109,23 +893,18 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
                      vertices_per_cell = GeometryInfo<3>::vertices_per_cell;
 
   static const StraightBoundary<3> straight_boundary;
-  // used if face quad at boundary or
-  // entirely in the interior of the
-  // domain
+  // used if face quad at boundary or entirely in the interior of the domain
   std::vector<Point<3> > quad_points ((degree-1)*(degree-1));
-  // used if only one line of face
-  // quad is at boundary
+  // used if only one line of face quad is at boundary
   std::vector<Point<3> > b(4*degree);
 
 
-  // loop over all faces and collect
-  // points on them
+  // loop over all faces and collect points on them
   for (unsigned int face_no=0; face_no<faces_per_cell; ++face_no)
     {
       const Triangulation<3>::face_iterator face = cell->face(face_no);
 
-      // select the correct mappings
-      // for the present face
+      // select the correct mappings for the present face
       const bool face_orientation = cell->face_orientation(face_no),
                  face_flip        = cell->face_flip       (face_no),
                  face_rotation    = cell->face_rotation   (face_no);
@@ -1140,9 +919,7 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
                                                         face_rotation)),
                ExcInternalError());
 
-      // indices of the lines that
-      // bound a face are given by
-      // GeometryInfo<3>::
+      // indices of the lines that bound a face are given by GeometryInfo<3>::
       // face_to_cell_lines
       for (unsigned int i=0; i<lines_per_face; ++i)
         Assert(face->line(i)==cell->line(GeometryInfo<3>::face_to_cell_lines(
@@ -1150,22 +927,16 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
                ExcInternalError());
 #endif
 
-      // if face at boundary, then
-      // ask boundary object to
-      // return intermediate points
-      // on it
+      // if face at boundary, then ask boundary object to return intermediate
+      // points on it
       if (face->at_boundary())
         {
           face->get_triangulation().get_boundary(face->boundary_indicator())
           .get_intermediate_points_on_quad (face, quad_points);
-          // in 3D, the orientation, flip and
-          // rotation of the face might not
-          // match what we expect here, namely
-          // the standard orientation. thus
-          // reorder points accordingly. since
-          // a Mapping uses the same shape
-          // function as an FEQ, we can ask a
-          // FEQ to do the reordering for us.
+          // in 3D, the orientation, flip and rotation of the face might not
+          // match what we expect here, namely the standard orientation. thus
+          // reorder points accordingly. since a Mapping uses the same shape
+          // function as an FEQ, we can ask a FEQ to do the reordering for us.
           for (unsigned int i=0; i<quad_points.size(); ++i)
             a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
                                     face_orientation,
@@ -1174,9 +945,8 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
         }
       else
         {
-          // face is not at boundary,
-          // but maybe some of its
-          // lines are. count them
+          // face is not at boundary, but maybe some of its lines are. count
+          // them
           unsigned int lines_at_boundary=0;
           for (unsigned int i=0; i<lines_per_face; ++i)
             if (face->line(i)->at_boundary())
@@ -1184,37 +954,23 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
 
           Assert(lines_at_boundary<=lines_per_face, ExcInternalError());
 
-          // if at least one of the
-          // lines bounding this quad
-          // is at the boundary, then
-          // collect points
-          // separately
+          // if at least one of the lines bounding this quad is at the
+          // boundary, then collect points separately
           if (lines_at_boundary>0)
             {
-              // call of function
-              // apply_laplace_vector
-              // increases size of b
-              // about 1. There
-              // resize b for the
-              // case the mentioned
-              // function was already
-              // called.
+              // call of function apply_laplace_vector increases size of b
+              // about 1. There resize b for the case the mentioned function
+              // was already called.
               b.resize(4*degree);
 
-              // b is of size
-              // 4*degree, make sure
-              // that this is the
-              // right size
+              // b is of size 4*degree, make sure that this is the right size
               Assert(b.size()==vertices_per_face+lines_per_face*(degree-1),
                      ExcDimensionMismatch(b.size(),
                                           vertices_per_face+lines_per_face*(degree-1)));
 
-              // sort the points into b. We
-              // used access from the cell (not
-              // from the face) to fill b, so
-              // we can assume a standard face
-              // orientation. Doing so, the
-              // calculated points will be in
+              // sort the points into b. We used access from the cell (not
+              // from the face) to fill b, so we can assume a standard face
+              // orientation. Doing so, the calculated points will be in
               // standard orientation as well.
               for (unsigned int i=0; i<vertices_per_face; ++i)
                 b[i]=a[GeometryInfo<3>::face_to_cell_vertices(face_no, i)];
@@ -1225,8 +981,7 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
                     a[vertices_per_cell + GeometryInfo<3>::face_to_cell_lines(
                         face_no, i)*(degree-1)+j];
 
-              // Now b includes the support
-              // points on the quad and we can
+              // Now b includes the support points on the quad and we can
               // apply the laplace vector
               apply_laplace_vector(laplace_on_quad_vector, b);
               Assert(b.size()==4*degree+(degree-1)*(degree-1),
@@ -1237,22 +992,14 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
             }
           else
             {
-              // face is entirely in
-              // the interior. get
-              // intermediate points
-              // from a straight
-              // boundary object
+              // face is entirely in the interior. get intermediate points
+              // from a straight boundary object
               straight_boundary.get_intermediate_points_on_quad (face, quad_points);
-              // in 3D, the orientation, flip
-              // and rotation of the face might
-              // not match what we expect here,
-              // namely the standard
-              // orientation. thus reorder
-              // points accordingly. since a
-              // Mapping uses the same shape
-              // function as an FEQ, we can ask
-              // a FEQ to do the reordering for
-              // us.
+              // in 3D, the orientation, flip and rotation of the face might
+              // not match what we expect here, namely the standard
+              // orientation. thus reorder points accordingly. since a Mapping
+              // uses the same shape function as an FEQ, we can ask a FEQ to
+              // do the reordering for us.
               for (unsigned int i=0; i<quad_points.size(); ++i)
                 a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
                                         face_orientation,
@@ -1301,31 +1048,24 @@ MappingQ<dim,spacedim>::transform (
   const MappingType mapping_type) const
 {
   AssertDimension (input.size(), output.size());
-  // The data object may be just a
-  // MappingQ1::InternalData, so we
-  // have to test for this first.
+  // The data object may be just a MappingQ1::InternalData, so we have to test
+  // for this first.
   const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
     dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
 
-  // If it is a genuine
-  // MappingQ::InternalData, we have
-  // to test further
+  // If it is a genuine MappingQ::InternalData, we have to test further
   if (!q1_data->is_mapping_q1_data)
     {
       Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
               ExcInternalError());
       const InternalData &data = static_cast<const InternalData &>(mapping_data);
-      // If we only use the
-      // Q1-portion, we have to
-      // extract that data object
+      // If we only use the Q1-portion, we have to extract that data object
       if (data.use_mapping_q1_on_current_cell)
         q1_data = &data.mapping_q1_data;
     }
-  // Now, q1_data should have the
-  // right tensors in it and we call
-  // the base classes transform
-  // function
+  // Now, q1_data should have the right tensors in it and we call the base
+  // classes transform function
   MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
 }
 
@@ -1340,31 +1080,24 @@ MappingQ<dim,spacedim>::transform (
   const MappingType mapping_type) const
 {
   AssertDimension (input.size(), output.size());
-  // The data object may be just a
-  // MappingQ1::InternalData, so we
-  // have to test for this first.
+  // The data object may be just a MappingQ1::InternalData, so we have to test
+  // for this first.
   const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
     dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
 
-  // If it is a genuine
-  // MappingQ::InternalData, we have
-  // to test further
+  // If it is a genuine MappingQ::InternalData, we have to test further
   if (!q1_data->is_mapping_q1_data)
     {
       Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
               ExcInternalError());
       const InternalData &data = static_cast<const InternalData &>(mapping_data);
-      // If we only use the
-      // Q1-portion, we have to
-      // extract that data object
+      // If we only use the Q1-portion, we have to extract that data object
       if (data.use_mapping_q1_on_current_cell)
         q1_data = &data.mapping_q1_data;
     }
-  // Now, q1_data should have the
-  // right tensors in it and we call
-  // the base classes transform
-  // function
+  // Now, q1_data should have the right tensors in it and we call the base
+  // classes transform function
   MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
 }
 
@@ -1377,31 +1110,24 @@ void MappingQ<dim,spacedim>::transform
  const MappingType mapping_type) const
 {
   AssertDimension (input.size(), output.size());
-  // The data object may be just a
-  // MappingQ1::InternalData, so we
-  // have to test for this first.
+  // The data object may be just a MappingQ1::InternalData, so we have to test
+  // for this first.
   const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
     dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
   Assert(q1_data!=0, ExcInternalError());
 
-  // If it is a genuine
-  // MappingQ::InternalData, we have
-  // to test further
+  // If it is a genuine MappingQ::InternalData, we have to test further
   if (!q1_data->is_mapping_q1_data)
     {
       Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
               ExcInternalError());
       const InternalData &data = static_cast<const InternalData &>(mapping_data);
-      // If we only use the
-      // Q1-portion, we have to
-      // extract that data object
+      // If we only use the Q1-portion, we have to extract that data object
       if (data.use_mapping_q1_on_current_cell)
         q1_data = &data.mapping_q1_data;
     }
-  // Now, q1_data should have the
-  // right tensors in it and we call
-  // the base classes transform
-  // function
+  // Now, q1_data should have the right tensors in it and we call the base
+  // classes transform function
   MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
 }
 
@@ -1412,11 +1138,9 @@ MappingQ<dim,spacedim>::
 transform_unit_to_real_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                              const Point<dim>                                 &p) const
 {
-  // Use the get_data function to
-  // create an InternalData with data
-  // vectors of the right size and
-  // transformation shape values
-  // already computed at point p.
+  // Use the get_data function to create an InternalData with data vectors of
+  // the right size and transformation shape values already computed at point
+  // p.
   const Quadrature<dim> point_quadrature(p);
   std::auto_ptr<InternalData>
   mdata (dynamic_cast<InternalData *> (
@@ -1431,8 +1155,7 @@ transform_unit_to_real_cell (const typename Triangulation<dim,spacedim>::cell_it
              &*mdata);
 
   compute_mapping_support_points(cell, p_data->mapping_support_points);
-  // If this should be Q1, ignore all
-  // other support points.
+  // If this should be Q1, ignore all other support points.
   if (p_data->shape_values.size()<p_data->mapping_support_points.size())
     p_data->mapping_support_points.resize
     (GeometryInfo<dim>::vertices_per_cell);
@@ -1449,24 +1172,15 @@ MappingQ<dim,spacedim>::
 transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
                              const Point<spacedim>                            &p) const
 {
-  // first a Newton iteration based
-  // on a Q1 mapping to get a good
-  // starting point, the idea being
-  // that this is cheaper than trying
-  // to start with the real mapping
-  // and likely also more robust.
+  // first a Newton iteration based on a Q1 mapping to get a good starting
+  // point, the idea being that this is cheaper than trying to start with the
+  // real mapping and likely also more robust.
   //
-  // that said, this doesn't always
-  // work: there are cases where the
-  // point is outside the cell and
-  // the inverse mapping doesn't
-  // converge. in that case, use the
-  // center point of the cell as a
-  // starting point if we are to go
-  // on using the full mapping, or
-  // just propagate up the exception
-  // if we had no intention of
-  // continuing with the full mapping
+  // that said, this doesn't always work: there are cases where the point is
+  // outside the cell and the inverse mapping doesn't converge. in that case,
+  // use the center point of the cell as a starting point if we are to go on
+  // using the full mapping, or just propagate up the exception if we had no
+  // intention of continuing with the full mapping
   Point<dim> initial_p_unit;
   try
     {
@@ -1475,11 +1189,8 @@ transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_it
     }
   catch (const typename Mapping<dim,spacedim>::ExcTransformationFailed &)
     {
-      // mirror the conditions of the
-      // code below to determine if
-      // we need to use an arbitrary
-      // starting point or if we just
-      // need to rethrow the
+      // mirror the conditions of the code below to determine if we need to
+      // use an arbitrary starting point or if we just need to rethrow the
       // exception
       if (cell->has_boundary_lines()
           ||
@@ -1494,30 +1205,22 @@ transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_it
         throw;
     }
 
-  // then a Newton iteration based on the
-  // full MappingQ if we need this. note that
-  // for interior cells with dim==spacedim,
-  // the mapping used is in fact a Q1
-  // mapping, so there is nothing we need to
-  // do unless the iteration above failed
+  // then a Newton iteration based on the full MappingQ if we need this. note
+  // that for interior cells with dim==spacedim, the mapping used is in fact a
+  // Q1 mapping, so there is nothing we need to do unless the iteration above
+  // failed
   if (cell->has_boundary_lines()
       ||
       use_mapping_q_on_all_cells
       ||
       (dim!=spacedim) )
     {
-      // use the full mapping. in case the
-      // function above should have given us
-      // something back that lies outside the
-      // unit cell (that might happen because
-      // we may have given a point 'p' that
-      // lies inside the cell with the higher
-      // order mapping, but outside the
-      // Q1-mapped reference cell), then
-      // project it back into the reference
-      // cell in hopes that this gives a
-      // better starting point to the
-      // following iteration
+      // use the full mapping. in case the function above should have given us
+      // something back that lies outside the unit cell (that might happen
+      // because we may have given a point 'p' that lies inside the cell with
+      // the higher order mapping, but outside the Q1-mapped reference cell),
+      // then project it back into the reference cell in hopes that this gives
+      // a better starting point to the following iteration
       initial_p_unit = GeometryInfo<dim>::project_to_unit_cell(initial_p_unit);
 
       const Quadrature<dim> point_quadrature(initial_p_unit);
@@ -1533,13 +1236,11 @@ transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_it
 
       compute_mapping_support_points (cell, mdata->mapping_support_points);
 
-      // If this is a q1 mapping,
-      // then only use the support
-      // points on the vertices.
+      // If this is a q1 mapping, then only use the support points on the
+      // vertices.
       if (mdata->shape_values.size() < mdata->mapping_support_points.size())
         mdata->mapping_support_points.resize(GeometryInfo<dim>::vertices_per_cell);
 
-
       return this->transform_real_to_unit_cell_internal(cell, p, initial_p_unit, *mdata);
     }
   else
index c8ba7374746cc74fef9a4a8b1b01953d25fd7886..902c6cd3592a3d6cd24ad237a43ce77ad841aaa5 100644 (file)
@@ -71,20 +71,15 @@ SupportQuadrature (const unsigned int map_degree)
   :
   Quadrature<dim>(Utilities::fixed_power<dim>(map_degree+1))
 {
-  // first we determine the support points
-  // on the unit cell in lexicographic order.
-  // for this purpose we can use an interated
-  // trapezoidal quadrature rule.
-  const QTrapez<1> q1d;
-  const QIterated<dim> q_iterated(q1d,map_degree);
+  // first we determine the support points on the unit cell in lexicographic
+  // order, which are (in accordance with MappingQ) the support points of
+  // QGaussLobatto.
+  const QGaussLobatto<dim> q_iterated(map_degree+1);
   const unsigned int n_q_points = q_iterated.size();
 
-  // we then need to define a renumbering
-  // vector that allows us to go from a
-  // lexicographic numbering scheme to a hierarchic
-  // one.  this fragment is taking almost verbatim
-  // from the MappingQ class.
-
+  // we then need to define a renumbering vector that allows us to go from a
+  // lexicographic numbering scheme to a hierarchic one.  this fragment is
+  // taking almost verbatim from the MappingQ class.
   std::vector<unsigned int> renumber(n_q_points);
   std::vector<unsigned int> dpo(dim+1, 1U);
   for (unsigned int i=1; i<dpo.size(); ++i)
@@ -93,9 +88,7 @@ SupportQuadrature (const unsigned int map_degree)
   FETools::lexicographic_to_hierarchic_numbering (
     FiniteElementData<dim> (dpo, 1, map_degree), renumber);
 
-  // finally we assign the quadrature points in the
-  // required order.
-
+  // finally we assign the quadrature points in the required order.
   for (unsigned int q=0; q<n_q_points; ++q)
     this->quadrature_points[renumber[q]] = q_iterated.point(q);
 }
@@ -112,43 +105,30 @@ compute_mapping_support_points
  std::vector<Point<spacedim> > &a) const
 {
 
-  // first, basic assertion
-  // with respect to vector size,
+  // first, basic assertion with respect to vector size,
 
   const types::global_dof_index n_dofs  = euler_dof_handler->n_dofs();
   const types::global_dof_index vector_size = euler_vector->size();
 
   AssertDimension(vector_size,n_dofs);
 
-  // we then transform our tria iterator
-  // into a dof iterator so we can
-  // access data not associated with
-  // triangulations
+  // we then transform our tria iterator into a dof iterator so we can access
+  // data not associated with triangulations
   typename DoFHandler<dim,spacedim>::cell_iterator dof_cell(*cell, euler_dof_handler);
 
   Assert (dof_cell->active() == true, ExcInactiveCell());
 
-  // our quadrature rule is chosen
-  // so that each quadrature point
-  // corresponds to a support point
-  // in the undeformed configuration.
-  // we can then query the given
-  // displacement field at these points
-  // to determine the shift vector that
-  // maps the support points to the
-  // deformed configuration.
-
-  // we assume that the given field contains
-  // dim displacement components, but
-  // that there may be other solution
-  // components as well (e.g. pressures).
-  // this class therefore assumes that the
-  // first dim components represent the
-  // actual shift vector we need, and simply
-  // ignores any components after that.
-  // this implies that the user should order
-  // components appropriately, or create a
-  // separate dof handler for the displacements.
+  // our quadrature rule is chosen so that each quadrature point corresponds
+  // to a support point in the undeformed configuration.  we can then query
+  // the given displacement field at these points to determine the shift
+  // vector that maps the support points to the deformed configuration.
+
+  // we assume that the given field contains dim displacement components, but
+  // that there may be other solution components as well (e.g. pressures).
+  // this class therefore assumes that the first dim components represent the
+  // actual shift vector we need, and simply ignores any components after
+  // that.  this implies that the user should order components appropriately,
+  // or create a separate dof handler for the displacements.
 
   const unsigned int n_support_pts = support_quadrature.size();
   const unsigned int n_components  = euler_dof_handler->get_fe().n_components();
@@ -157,20 +137,15 @@ compute_mapping_support_points
 
   std::vector<Vector<double> > shift_vector(n_support_pts,Vector<double>(n_components));
 
-  // fill shift vector for each
-  // support point using an fe_values
-  // object. make sure that the
-  // fe_values variable isn't used
-  // simulatenously from different
+  // fill shift vector for each support point using an fe_values object. make
+  // sure that the fe_values variable isn't used simulatenously from different
   // threads
   Threads::Mutex::ScopedLock lock(fe_values_mutex);
   fe_values.reinit(dof_cell);
   fe_values.get_function_values(*euler_vector, shift_vector);
 
-  // and finally compute the positions of the
-  // support points in the deformed
+  // and finally compute the positions of the support points in the deformed
   // configuration.
-
   a.resize(n_support_pts);
   for (unsigned int q=0; q<n_support_pts; ++q)
     {
@@ -196,8 +171,7 @@ MappingQEulerian<dim,EulerVectorType,spacedim>::fill_fe_values (
   std::vector<Point<spacedim> >                             &normal_vectors,
   CellSimilarity::Similarity                           &cell_similarity) const
 {
-  // disable any previously detected
-  // similarity and hand on to the respective
+  // disable any previously detected similarity and hand on to the respective
   // function of the base class.
   cell_similarity = CellSimilarity::invalid_next_cell;
   MappingQ<dim,spacedim>::fill_fe_values (cell, q, mapping_data,
index 839f3ff04b58f2b5fea893e7addef4c3233a243e..1a4892974582b60a5405255ac2ced2ee9fe286d0 100644 (file)
@@ -577,7 +577,7 @@ GridOut::declare_parameters(ParameterHandler &param)
   GridOutFlags::XFig::declare_parameters(param);
   param.leave_subsection();
 
-  param.enter_subsection("MathGl");
+  param.enter_subsection("MathGL");
   GridOutFlags::MathGL::declare_parameters(param);
   param.leave_subsection();
 }
index f956c1d16c3a4886733683590c5c18461597a794..65b3bafe7bb4e26c1320f961a9332e7f73e08ae8 100644 (file)
@@ -247,6 +247,33 @@ project_to_surface (const typename Triangulation<dim, spacedim>::hex_iterator &,
 }
 
 
+
+template <int dim, int spacedim>
+const std::vector<Point<1> > &
+Boundary<dim,spacedim>::
+get_line_support_points (const unsigned int n_intermediate_points) const
+{
+  if (points.size() <= n_intermediate_points ||
+      points[n_intermediate_points].get() == 0)
+    {
+      Threads::Mutex::ScopedLock lock(mutex);
+      if (points.size() <= n_intermediate_points)
+        points.resize(n_intermediate_points+1);
+
+      // another thread might have created points in the meantime
+      if (points[n_intermediate_points].get() == 0)
+        {
+          std_cxx1x::shared_ptr<QGaussLobatto<1> >
+            quadrature (new QGaussLobatto<1>(n_intermediate_points+2));
+          points[n_intermediate_points] = quadrature;
+        }
+    }
+  return points[n_intermediate_points]->get_points();
+}
+
+
+
+
 /* -------------------------- StraightBoundary --------------------- */
 
 
@@ -394,15 +421,18 @@ get_intermediate_points_on_line (const Triangulation<1, 2>::line_iterator &line,
   const unsigned int n=points.size();
   Assert(n>0, ExcInternalError());
 
-  const double dx=1./(n+1);
-  double x=dx;
-
+  // Use interior points of QGaussLobatto quadrature formula support points
+  // for consistency with MappingQ
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
   const Point<spacedim> vertices[2] = { line->vertex(0),
                                         line->vertex(1)
                                       };
 
-  for (unsigned int i=0; i<n; ++i, x+=dx)
-    points[i] = (1-x)*vertices[0] + x*vertices[1];
+  for (unsigned int i=0; i<n; ++i)
+    {
+      const double x = line_points[i+1][0];
+      points[i] = (1-x)*vertices[0] + x*vertices[1];
+    }
 }
 
 
@@ -417,15 +447,19 @@ get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::li
   const unsigned int n=points.size();
   Assert(n>0, ExcInternalError());
 
-  const double dx=1./(n+1);
-  double x=dx;
+  // Use interior points of QGaussLobatto quadrature formula support points
+  // for consistency with MappingQ
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
 
   const Point<spacedim> vertices[2] = { line->vertex(0),
                                         line->vertex(1)
                                       };
 
-  for (unsigned int i=0; i<n; ++i, x+=dx)
-    points[i] = (1-x)*vertices[0] + x*vertices[1];
+  for (unsigned int i=0; i<n; ++i)
+    {
+      const double x = line_points[1+i][0];
+      points[i] = (1-x)*vertices[0] + x*vertices[1];
+    }
 }
 
 
@@ -455,8 +489,7 @@ get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
   // is n a square number
   Assert(m*m==n, ExcInternalError());
 
-  const double ds=1./(m+1);
-  double y=ds;
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(m);
 
   const Point<spacedim> vertices[4] = { quad->vertex(0),
                                         quad->vertex(1),
@@ -464,14 +497,17 @@ get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
                                         quad->vertex(3)
                                       };
 
-  for (unsigned int i=0; i<m; ++i, y+=ds)
+  for (unsigned int i=0; i<m; ++i)
     {
-      double x=ds;
-      for (unsigned int j=0; j<m; ++j, x+=ds)
-        points[i*m+j]=((1-x) * vertices[0] +
-                       x     * vertices[1]) * (1-y) +
-                      ((1-x) * vertices[2] +
-                       x     * vertices[3]) * y;
+      const double y=line_points[1+i][0];
+      for (unsigned int j=0; j<m; ++j)
+        {
+          const double x=line_points[1+j][0];
+          points[i*m+j]=((1-x) * vertices[0] +
+                         x     * vertices[1]) * (1-y) +
+                        ((1-x) * vertices[2] +
+                         x     * vertices[3]) * y;
+        }
     }
 }
 
@@ -490,8 +526,7 @@ get_intermediate_points_on_quad (const Triangulation<2,3>::quad_iterator &quad,
   // is n a square number
   Assert(m*m==n, ExcInternalError());
 
-  const double ds=1./(m+1);
-  double y=ds;
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(m);
 
   const Point<spacedim> vertices[4] = { quad->vertex(0),
                                         quad->vertex(1),
@@ -499,14 +534,17 @@ get_intermediate_points_on_quad (const Triangulation<2,3>::quad_iterator &quad,
                                         quad->vertex(3)
                                       };
 
-  for (unsigned int i=0; i<m; ++i, y+=ds)
+  for (unsigned int i=0; i<m; ++i)
     {
-      double x=ds;
-      for (unsigned int j=0; j<m; ++j, x+=ds)
-        points[i*m+j]=((1-x) * vertices[0] +
-                       x     * vertices[1]) * (1-y) +
-                      ((1-x) * vertices[2] +
-                       x     * vertices[3]) * y;
+      const double y=line_points[1+i][0];
+      for (unsigned int j=0; j<m; ++j)
+        {
+          const double x=line_points[1+j][0];
+          points[i*m+j]=((1-x) * vertices[0] +
+                         x     * vertices[1]) * (1-y) +
+                        ((1-x) * vertices[2] +
+                         x     * vertices[3]) * y;
+        }
     }
 }
 
index df1f4e991126968a1602937a0df630f9d5b536c4..1cbd41c77a3848531d5927b8cebe859081c39d2b 100644 (file)
@@ -165,14 +165,14 @@ CylinderBoundary<dim,spacedim>::get_intermediate_points_between_points (
   const unsigned int n=points.size();
   Assert(n>0, ExcInternalError());
 
-  // Do a simple linear interpolation
-  // followed by projection, using
-  // the same algorithm as above
-  const Point<spacedim> ds = (v1-v0) / (n+1);
+  // Do a simple linear interpolation followed by projection, using the same
+  // algorithm as above
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
 
   for (unsigned int i=0; i<n; ++i)
     {
-      const Point<spacedim> middle = v0 + (i+1)*ds;
+      const double x = line_points[i+1][0];
+      const Point<spacedim> middle = (1-x)*v0 + x*v1;
 
       const Point<spacedim> vector_from_axis = (middle-point_on_axis) -
                                                ((middle-point_on_axis) * direction) * direction;
@@ -307,24 +307,23 @@ get_intermediate_points_between_points (const Point<dim> &p0,
 {
   const unsigned int n = points.size ();
   const Point<dim> axis = x_1 - x_0;
-  const Point<dim> dx = (p1 - p0) / (n + 1);
 
   Assert (n > 0, ExcInternalError ());
 
-  for (unsigned int i = 0; i < n; ++i)
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
+
+  for (unsigned int i=0; i<n; ++i)
     {
+      const double x = line_points[i+1][0];
+
       // Compute the current point.
-      const Point<dim> x_i = p0 + (i + 1) * dx;
-      // To project this point on the
-      // boundary of the cone we first
-      // compute the orthogonal
-      // projection of this point onto
-      // the axis of the cone.
+      const Point<dim> x_i = (1-x)*p0 + x*p1;
+      // To project this point on the boundary of the cone we first compute
+      // the orthogonal projection of this point onto the axis of the cone.
       const double c = (x_i - x_0) * axis / axis.square ();
       const Point<dim> x_ip = x_0 + c * axis;
-      // Compute the projection of
-      // the middle point on the
-      // boundary of the cone.
+      // Compute the projection of the middle point on the boundary of the
+      // cone.
       points[i] = x_ip + get_radius (x_ip) *  (x_i - x_ip) / (x_i - x_ip).norm ();
     }
 }
@@ -337,16 +336,11 @@ get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) c
   const Point<dim> axis = x_1 - x_0;
   // Compute the middle point of the line.
   const Point<dim> middle = StraightBoundary<dim>::get_new_point_on_line (line);
-  // To project it on the boundary of
-  // the cone we first compute the
-  // orthogonal projection of the
-  // middle point onto the axis of
-  // the cone.
+  // To project it on the boundary of the cone we first compute the orthogonal
+  // projection of the middle point onto the axis of the cone.
   const double c = (middle - x_0) * axis / axis.square ();
   const Point<dim> middle_p = x_0 + c * axis;
-  // Compute the projection of the
-  // middle point on the boundary
-  // of the cone.
+  // Compute the projection of the middle point on the boundary of the cone.
   return middle_p + get_radius (middle_p) * (middle - middle_p) / (middle - middle_p).norm ();
 }
 
@@ -360,20 +354,14 @@ get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const
   const int dim = 3;
 
   const Point<dim> axis = x_1 - x_0;
-  // Compute the middle point of the
-  // quad.
+  // Compute the middle point of the quad.
   const Point<dim> middle = StraightBoundary<3>::get_new_point_on_quad (quad);
-  // Same algorithm as above: To
-  // project it on the boundary of
-  // the cone we first compute the
-  // orthogonal projection of the
-  // middle point onto the axis of
-  // the cone.
+  // Same algorithm as above: To project it on the boundary of the cone we
+  // first compute the orthogonal projection of the middle point onto the axis
+  // of the cone.
   const double c = (middle - x_0) * axis / axis.square ();
   const Point<dim> middle_p = x_0 + c * axis;
-  // Compute the projection of the
-  // middle point on the boundary
-  // of the cone.
+  // Compute the projection of the middle point on the boundary of the cone.
   return middle_p + get_radius (middle_p) * (middle - middle_p) / (middle - middle_p).norm ();
 }
 
@@ -475,15 +463,12 @@ get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
 
   for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell; ++vertex)
     {
-      // Compute the orthogonal
-      // projection of the vertex onto
-      // the axis of the cone.
+      // Compute the orthogonal projection of the vertex onto the axis of the
+      // cone.
       const double c = (face->vertex (vertex) - x_0) * axis / axis.square ();
       const Point<dim> vertex_p = x_0 + c * axis;
-      // Then compute the vector
-      // pointing from the point
-      // <tt>vertex_p</tt> on the axis
-      // to the vertex.
+      // Then compute the vector pointing from the point <tt>vertex_p</tt> on
+      // the axis to the vertex.
       const Point<dim> axis_to_vertex = face->vertex (vertex) - vertex_p;
 
       face_vertex_normals[vertex] = axis_to_vertex / axis_to_vertex.norm ();
@@ -629,49 +614,28 @@ HyperBallBoundary<dim,spacedim>::get_intermediate_points_between_points (
   Assert(std::fabs(v1.square()-r2)<eps*r2, ExcInternalError());
 
   const double alpha=std::acos((v0*v1)/std::sqrt(v0.square()*v1.square()));
-  const double d_alpha=alpha/(n+1);
   const Point<spacedim> pm=0.5*(v0+v1);
 
   const double h=std::sqrt(pm.square());
 
-  double beta=0;
-  unsigned int left_index=0, right_index=0;
-  if ((n+1)%2==0)
-    {
-      // if the number of
-      // parts is even insert
-      // the midpoint
-      left_index=(n-1)/2;
-      right_index=left_index;
-      points[left_index]=pm;
-      --left_index;
-      ++right_index;
-      beta=d_alpha;
-    }
-  else
-    {
-      beta=(n/2+1)*d_alpha-alpha/2.;
-      right_index=n/2;
-      left_index=n/2-1;
-    }
-
   // n even:  m=n/2,
   // n odd:   m=(n-1)/2
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
   const unsigned int m=n/2;
-  for (unsigned int i=0; i<m ; ++i, ++right_index, --left_index, beta+=d_alpha)
+  for (unsigned int i=0; i<m ; ++i)
     {
-      Assert(right_index<n, ExcInternalError());
-      Assert(left_index+1>=1, ExcInternalError());
-
-      double d=h*std::tan(beta);
-      points[right_index]=pm+d/length*(v1-v0);
-      points[left_index]=pm-d/length*(v1-v0);
+      const double beta = alpha * (line_points[i+1][0]-0.5);
+      const double d=h*std::tan(beta);
+      points[i]=pm+d/length*(v1-v0);
+      points[n-1-i]=pm-d/length*(v1-v0);
     }
 
+  if ((n+1)%2==0)
+    // if the number of parts is even insert the midpoint
+    points[(n-1)/2]=pm;
 
-  // project the points from the
-  // straight line to the
-  // HyperBallBoundary
+
+  // project the points from the straight line to the HyperBallBoundary
   for (unsigned int i=0; i<n; ++i)
     {
       points[i] *= r / std::sqrt(points[i].square());
@@ -885,10 +849,8 @@ HalfHyperBallBoundary<dim>::
 get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
                                  std::vector<Point<dim> > &points) const
 {
-  // check whether center of object is
-  // at x==0, since then it belongs
-  // to the plane part of the
-  // boundary
+  // check whether center of object is at x==0, since then it belongs to the
+  // plane part of the boundary
   const Point<dim> line_center = line->center();
   if (line_center(0) == this->center(0))
     return StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
@@ -908,10 +870,8 @@ get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterato
     points[0]=get_new_point_on_quad(quad);
   else
     {
-      // check whether center of
-      // object is at x==0, since
-      // then it belongs to the plane
-      // part of the boundary
+      // check whether center of object is at x==0, since then it belongs to
+      // the plane part of the boundary
       const Point<dim> quad_center = quad->center();
       if (quad_center(0) == this->center(0))
         StraightBoundary<dim>::get_intermediate_points_on_quad (quad, points);
@@ -950,10 +910,8 @@ HalfHyperBallBoundary<dim>::
 get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
                          typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
 {
-  // check whether center of object is
-  // at x==0, since then it belongs
-  // to the plane part of the
-  // boundary
+  // check whether center of object is at x==0, since then it belongs to the
+  // plane part of the boundary
   const Point<dim> quad_center = face->center();
   if (quad_center(0) == this->center(0))
     StraightBoundary<dim>::get_normals_at_vertices (face, face_vertex_normals);
@@ -1005,10 +963,8 @@ get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) c
 {
   switch (dim)
     {
-      // in 2d, first check whether the two
-      // end points of the line are on the
-      // axis of symmetry. if so, then return
-      // the mid point
+      // in 2d, first check whether the two end points of the line are on the
+      // axis of symmetry. if so, then return the mid point
     case 2:
     {
       if ((line->vertex(0)(0) == this->center(0))
@@ -1016,17 +972,13 @@ get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) c
           (line->vertex(1)(0) == this->center(0)))
         return (line->vertex(0) + line->vertex(1))/2;
       else
-        // otherwise we are on the outer or
-        // inner part of the shell. proceed
+        // otherwise we are on the outer or inner part of the shell. proceed
         // as in the base class
         return HyperShellBoundary<dim>::get_new_point_on_line (line);
     }
 
-    // in 3d, a line is a straight
-    // line if it is on the symmetry
-    // plane and if not both of its
-    // end points are on either the
-    // inner or outer sphere
+    // in 3d, a line is a straight line if it is on the symmetry plane and if
+    // not both of its end points are on either the inner or outer sphere
     case 3:
     {
 
@@ -1047,8 +999,7 @@ get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) c
                          - outer_radius) < 1e-12 * outer_radius))))
         return (line->vertex(0) + line->vertex(1))/2;
       else
-        // otherwise we are on the outer or
-        // inner part of the shell. proceed
+        // otherwise we are on the outer or inner part of the shell. proceed
         // as in the base class
         return HyperShellBoundary<dim>::get_new_point_on_line (line);
     }
@@ -1079,10 +1030,8 @@ Point<dim>
 HalfHyperShellBoundary<dim>::
 get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const
 {
-  // if this quad is on the symmetry plane,
-  // take the center point and project it
-  // outward to the same radius as the
-  // centers of the two radial lines
+  // if this quad is on the symmetry plane, take the center point and project
+  // it outward to the same radius as the centers of the two radial lines
   if ((quad->vertex(0)(0) == this->center(0)) &&
       (quad->vertex(1)(0) == this->center(0)) &&
       (quad->vertex(2)(0) == this->center(0)) &&
@@ -1119,9 +1068,8 @@ get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) c
         Assert (false, ExcInternalError());
     }
 
-  // otherwise we are on the outer or
-  // inner part of the shell. proceed
-  // as in the base class
+  // otherwise we are on the outer or inner part of the shell. proceed as in
+  // the base class
   return HyperShellBoundary<dim>::get_new_point_on_quad (quad);
 }
 
@@ -1135,10 +1083,8 @@ get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterato
 {
   switch (dim)
     {
-      // in 2d, first check whether the two
-      // end points of the line are on the
-      // axis of symmetry. if so, then return
-      // the mid point
+      // in 2d, first check whether the two end points of the line are on the
+      // axis of symmetry. if so, then return the mid point
     case 2:
     {
       if ((line->vertex(0)(0) == this->center(0))
@@ -1146,18 +1092,14 @@ get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterato
           (line->vertex(1)(0) == this->center(0)))
         StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
       else
-        // otherwise we are on the outer or
-        // inner part of the shell. proceed
+        // otherwise we are on the outer or inner part of the shell. proceed
         // as in the base class
         HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
       break;
     }
 
-    // in 3d, a line is a straight
-    // line if it is on the symmetry
-    // plane and if not both of its
-    // end points are on either the
-    // inner or outer sphere
+    // in 3d, a line is a straight line if it is on the symmetry plane and if
+    // not both of its end points are on either the inner or outer sphere
     case 3:
     {
       if (((line->vertex(0)(0) == this->center(0))
@@ -1177,8 +1119,7 @@ get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterato
                          - outer_radius) < 1e-12 * outer_radius))))
         StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
       else
-        // otherwise we are on the outer or
-        // inner part of the shell. proceed
+        // otherwise we are on the outer or inner part of the shell. proceed
         // as in the base class
         HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
 
@@ -1200,10 +1141,8 @@ get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterato
 {
   Assert (dim < 3, ExcNotImplemented());
 
-  // check whether center of object is
-  // at x==0, since then it belongs
-  // to the plane part of the
-  // boundary
+  // check whether center of object is at x==0, since then it belongs to the
+  // plane part of the boundary
   const Point<dim> quad_center = quad->center();
   if (quad_center(0) == this->center(0))
     StraightBoundary<dim>::get_intermediate_points_on_quad (quad, points);
@@ -1350,9 +1289,9 @@ TorusBoundary<2,3>::get_new_point_on_line (const Triangulation<2,3>::line_iterat
 
   Point<2>  middle(0,0);
 
-  //Take care for periodic conditions,
-  //For instance phi0= 0, phi1= 3/2*Pi  middle has to be 7/4*Pi not 3/4*Pi
-  //This also works for -Pi/2 + Pi, middle is 5/4*Pi
+  //Take care for periodic conditions, For instance phi0= 0, phi1= 3/2*Pi
+  //middle has to be 7/4*Pi not 3/4*Pi. This also works for -Pi/2 + Pi, middle
+  //is 5/4*Pi
   for (unsigned int i=0; i<2; i++)
     if (std::abs(p0(i)-p1(i))> numbers::PI)
       middle(i)=2*numbers::PI;
@@ -1440,7 +1379,7 @@ TorusBoundary<2,3>::
 get_intermediate_points_on_line (const Triangulation<2, 3>::line_iterator   &line,
                                  std::vector< Point< 3 > > &points) const
 {
-  //Almost the same implementation as  StraightBoundary<2,3>
+  //Almost the same implementation as StraightBoundary<2,3>
   unsigned int npoints=points.size();
   if (npoints==0) return;
 
@@ -1453,10 +1392,10 @@ get_intermediate_points_on_line (const Triangulation<2, 3>::line_iterator   &lin
   offset[0]=0;
   offset[1]=0;
 
-  //Take care for periodic conditions & negative angles,
-  //see get_new_point_on_line() above
-  //Because we dont have a symmetric interpolation (just the middle) we need to
-  //add 2*Pi to each almost zero and negative angles.
+  //Take care for periodic conditions & negative angles, see
+  //get_new_point_on_line() above. Because we dont have a symmetric
+  //interpolation (just the middle) we need to add 2*Pi to each almost zero
+  //and negative angles.
   for (unsigned int i=0; i<2; i++)
     for (unsigned int j=1; j<2; j++)
       {
@@ -1473,11 +1412,11 @@ get_intermediate_points_on_line (const Triangulation<2, 3>::line_iterator   &lin
         p[j](i)+=2*numbers::PI*offset[i];
 
 
-  double dx=1.0/(npoints+1);
-  double x=dx;
   Point<2>  target;
-  for (unsigned int i=0; i<npoints; i++,x+=dx)
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(npoints);
+  for (unsigned int i=0; i<npoints; i++)
     {
+      const double x = line_points[i+1][0];
       target=  (1-x)*p[0] + x*p[1];
       points[i]=get_real_coord(target);
     }
@@ -1497,9 +1436,6 @@ get_intermediate_points_on_quad (const Triangulation< 2, 3 >::quad_iterator &qua
   // is n a square number
   Assert(m*m==n, ExcInternalError());
 
-  const double ds=1./(m+1);
-  double y=ds;
-
   Point<2>  p[4];
 
   for (unsigned int i=0; i<4; i++)
@@ -1510,10 +1446,10 @@ get_intermediate_points_on_quad (const Triangulation< 2, 3 >::quad_iterator &qua
   offset[0]=0;
   offset[1]=0;
 
-  //Take care for periodic conditions & negative angles,
-  //see get_new_point_on_line() above
-  //Because we dont have a symmetric interpolation (just the middle) we need to
-  //add 2*Pi to each almost zero and negative angles.
+  //Take care for periodic conditions & negative angles, see
+  //get_new_point_on_line() above.  Because we dont have a symmetric
+  //interpolation (just the middle) we need to add 2*Pi to each almost zero
+  //and negative angles.
   for (unsigned int i=0; i<2; i++)
     for (unsigned int j=1; j<4; j++)
       {
@@ -1529,11 +1465,13 @@ get_intermediate_points_on_quad (const Triangulation< 2, 3 >::quad_iterator &qua
       if (p[j](i)<1.E-12 ) //Take care for periodic conditions & negative angles
         p[j](i)+=2*numbers::PI*offset[i];
 
-  for (unsigned int i=0; i<m; ++i, y+=ds)
+  const std::vector<Point<1> > &line_points = this->get_line_support_points(m);
+  for (unsigned int i=0; i<m; ++i)
     {
-      double x=ds;
-      for (unsigned int j=0; j<m; ++j, x+=ds)
+      const double y=line_points[i+1][0];
+      for (unsigned int j=0; j<m; ++j)
         {
+          const double x=line_points[j+1][0];
           target=((1-x) * p[0] +
                   x     * p[1]) * (1-y) +
                  ((1-x) * p[2] +
index e436edf79ea2321d7e520abfa5f506033fae3cce..4e372994d1750ada63afb4579ccbbd8274dc881d 100644 (file)
@@ -50,7 +50,7 @@ namespace SLEPcWrappers
     :
     solver_control (cn),
     mpi_communicator (mpi_communicator),
-    target_eigenvalue (PETSC_NULL),
+    target_eigenvalue (0.),
     set_which (EPS_LARGEST_MAGNITUDE),
     set_problem (EPS_NHEP),
     opA (NULL),
@@ -110,8 +110,8 @@ namespace SLEPcWrappers
   }
 
   void
-  SolverBase::solve (const size_type  n_eigenpairs,
-                     size_type *n_converged)
+  SolverBase::solve (const unsigned int  n_eigenpairs,
+                     unsigned int *n_converged)
   {
     int ierr;
 
@@ -151,13 +151,17 @@ namespace SLEPcWrappers
         AssertThrow (ierr == 0, ExcSLEPcError(ierr));
       }
 
-    // set transformation type if any
+    // if a spectral transformation is to be used, set the
+    // transformation and target the wanted eigenvalues
     if (transformation)
-      transformation->set_context (solver_data->eps);
-
-    // set target eigenvalues to solve for
-    ierr = EPSSetTarget (solver_data->eps, target_eigenvalue);
-    AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+      {
+       // set transformation type if any
+       transformation->set_context (solver_data->eps);
+       
+       // set target eigenvalues to solve for
+       ierr = EPSSetTarget (solver_data->eps, target_eigenvalue);
+       AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+      }
 
     // set which portion of the eigenspectrum to solve for
     ierr = EPSSetWhichEigenpairs (solver_data->eps, set_which);
@@ -187,11 +191,11 @@ namespace SLEPcWrappers
 
     // get number of converged eigenstates
     ierr = EPSGetConverged (solver_data->eps,
-                            reinterpret_cast<PetscInt *>(n_converged));
+                            reinterpret_cast<PetscInt*>(n_converged));
     AssertThrow (ierr == 0, ExcSLEPcError(ierr));
 
-    PetscInt n_iterations = 0;
-    double residual_norm = 1e300;
+    PetscInt n_iterations   = 0;
+    PetscReal residual_norm = 1.e300;
 
     // @todo Investigate elaborating on some of this to act on the
     // complete eigenspectrum
@@ -200,9 +204,13 @@ namespace SLEPcWrappers
       ierr = EPSGetIterationNumber (solver_data->eps, &n_iterations);
       AssertThrow (ierr == 0, ExcSLEPcError(ierr));
 
-      // get the residual norm of the most extreme eigenvalue
-      ierr = EPSComputeResidualNorm (solver_data->eps, 0, &residual_norm);
-      AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+      // get the residual norm of the most extreme eigenvalue if and
+      // only if at least one eigenvector has converged.
+      if ((*n_converged)>0)
+       {
+         ierr = EPSComputeResidualNorm (solver_data->eps, 0, &residual_norm);
+         AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+       }
 
       // check the solver state
       const SolverControl::State state
@@ -219,7 +227,7 @@ namespace SLEPcWrappers
   }
 
   void
-  SolverBase::get_eigenpair (const size_type            index,
+  SolverBase::get_eigenpair (const unsigned int            index,
                              PetscScalar               &eigenvalues,
                              PETScWrappers::VectorBase &eigenvectors)
   {
index 855e2c677791a9510c0abc33c79d5660ee779933..df05c2eb6c97d7e344ef7e1007ac123c10d21148 100644 (file)
@@ -22,6 +22,7 @@ FILE(GLOB _header
 
 SET(_src
   data_out.cc
+  data_out_dof_data.cc
   data_out_faces.cc
   data_out_rotation.cc
   data_out_stack.cc
@@ -29,31 +30,50 @@ SET(_src
   derivative_approximation.cc
   dof_output_operator.cc
   error_estimator.cc
+  error_estimator_1d.cc
   fe_field_function.cc
   matrix_tools.cc
   histogram.cc
   point_value_history.cc
   solution_transfer.cc
   solution_transfer_inst2.cc
+  solution_transfer_inst3.cc
+  solution_transfer_inst4.cc
   time_dependent.cc
-  vector_tools.cc
+  vector_tools_boundary.cc
+  vector_tools_constraints.cc
+  vector_tools_integrate_difference.cc
+  vector_tools_interpolate.cc
+  vector_tools_mean_value.cc
+  vector_tools_point_value.cc
+  vector_tools_project.cc
+  vector_tools_rhs.cc
   )
 
 SET(_inst
-  data_out_faces.inst.in
   data_out.inst.in
+  data_out_dof_data.inst.in
+  data_out_faces.inst.in
   data_out_rotation.inst.in
   data_out_stack.inst.in
   data_postprocessor.inst.in
   derivative_approximation.inst.in
   dof_output_operator.inst.in
   error_estimator.inst.in
+  error_estimator_1d.inst.in
   fe_field_function.inst.in
   matrix_tools.inst.in
   point_value_history.inst.in
   solution_transfer.inst.in
   time_dependent.inst.in
-  vector_tools.inst.in
+  vector_tools_boundary.inst.in
+  vector_tools_constraints.inst.in
+  vector_tools_integrate_difference.inst.in
+  vector_tools_interpolate.inst.in
+  vector_tools_mean_value.inst.in
+  vector_tools_point_value.inst.in
+  vector_tools_project.inst.in
+  vector_tools_rhs.inst.in
   )
 
 DEAL_II_ADD_LIBRARY(obj_numerics OBJECT ${_src} ${_header} ${_inst})
index 79fd402ccb69d02239a713a1ff56e9febfb2ad1c..03e0cce91a1e16a2624a516831e7c2aedc2ced83 100644 (file)
 //
 // ---------------------------------------------------------------------
 
-#include <deal.II/base/quadrature_lib.h>
 #include <deal.II/base/work_stream.h>
-#include <deal.II/base/memory_consumption.h>
-#include <deal.II/lac/vector.h>
-#include <deal.II/lac/block_vector.h>
-#include <deal.II/lac/parallel_vector.h>
-#include <deal.II/lac/parallel_block_vector.h>
-#include <deal.II/lac/petsc_vector.h>
-#include <deal.II/lac/petsc_block_vector.h>
-#include <deal.II/lac/trilinos_vector.h>
-#include <deal.II/lac/trilinos_block_vector.h>
 #include <deal.II/numerics/data_out.h>
 #include <deal.II/grid/tria.h>
 #include <deal.II/dofs/dof_handler.h>
@@ -46,247 +36,6 @@ namespace internal
 {
   namespace DataOut
   {
-    template <int dim, int spacedim>
-    ParallelDataBase<dim,spacedim>::
-    ParallelDataBase (const unsigned int n_datasets,
-                      const unsigned int n_subdivisions,
-                      const std::vector<unsigned int> &n_postprocessor_outputs,
-                      const Mapping<dim,spacedim> &mapping,
-                      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
-                      const UpdateFlags update_flags,
-                      const bool        use_face_values)
-      :
-      n_datasets (n_datasets),
-      n_subdivisions (n_subdivisions),
-      postprocessed_values (n_postprocessor_outputs.size()),
-      mapping_collection (mapping),
-      finite_elements (finite_elements),
-      update_flags (update_flags)
-    {
-      unsigned int n_q_points = 0;
-      if (use_face_values == false)
-        {
-          dealii::hp::QCollection<dim>
-            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
-          n_q_points = quadrature[0].size();
-          x_fe_values.resize(this->finite_elements.size());
-          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
-            {
-              // check if there is a finite element that is equal to the
-              // present one, then we can re-use the FEValues object
-              for (unsigned int j=0; j<i; ++j)
-                if (this->finite_elements[i].get() ==
-                    this->finite_elements[j].get())
-                  {
-                    x_fe_values[i] = x_fe_values[j];
-                    break;
-                  }
-              if (x_fe_values[i].get() == 0)
-                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
-                                     (this->mapping_collection,
-                                      *this->finite_elements[i],
-                                      quadrature,
-                                      this->update_flags));
-            }
-        }
-      else
-        {
-          dealii::hp::QCollection<dim-1>
-            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
-          n_q_points = quadrature[0].size();
-          x_fe_face_values.resize(this->finite_elements.size());
-          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
-            {
-              // check if there is a finite element that is equal to the
-              // present one, then we can re-use the FEValues object
-              for (unsigned int j=0; j<i; ++j)
-                if (this->finite_elements[i].get() ==
-                    this->finite_elements[j].get())
-                  {
-                    x_fe_face_values[i] = x_fe_face_values[j];
-                    break;
-                  }
-              if (x_fe_face_values[i].get() == 0)
-                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
-                                          (this->mapping_collection,
-                                           *this->finite_elements[i],
-                                           quadrature,
-                                           this->update_flags));
-            }
-        }
-
-      patch_values.resize (n_q_points);
-      patch_values_system.resize (n_q_points);
-      patch_gradients.resize (n_q_points);
-      patch_gradients_system.resize (n_q_points);
-      patch_hessians.resize (n_q_points);
-      patch_hessians_system.resize (n_q_points);
-
-      for (unsigned int dataset=0; dataset<n_postprocessor_outputs.size(); ++dataset)
-        if (n_postprocessor_outputs[dataset] != 0)
-          postprocessed_values[dataset]
-          .resize(n_q_points,
-                  dealii::Vector<double>(n_postprocessor_outputs[dataset]));
-    }
-
-
-
-
-
-    // implement copy constructor to create a thread's own version of
-    // x_fe_values
-    template <int dim, int spacedim>
-    ParallelDataBase<dim,spacedim>::
-    ParallelDataBase (const ParallelDataBase<dim,spacedim> &data)
-      :
-      n_datasets (data.n_datasets),
-      n_subdivisions (data.n_subdivisions),
-      patch_values (data.patch_values),
-      patch_values_system (data.patch_values_system),
-      patch_gradients (data.patch_gradients),
-      patch_gradients_system (data.patch_gradients_system),
-      patch_hessians (data.patch_hessians),
-      patch_hessians_system (data.patch_hessians_system),
-      postprocessed_values (data.postprocessed_values),
-      mapping_collection (data.mapping_collection),
-      finite_elements (data.finite_elements),
-      update_flags (data.update_flags)
-    {
-      if (data.x_fe_values.empty() == false)
-        {
-          Assert(data.x_fe_face_values.empty() == true, ExcInternalError());
-          dealii::hp::QCollection<dim>
-            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
-          x_fe_values.resize(this->finite_elements.size());
-          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
-            {
-              // check if there is a finite element that is equal to the
-              // present one, then we can re-use the FEValues object
-              for (unsigned int j=0; j<i; ++j)
-                if (this->finite_elements[i].get() ==
-                    this->finite_elements[j].get())
-                  {
-                    x_fe_values[i] = x_fe_values[j];
-                    break;
-                  }
-              if (x_fe_values[i].get() == 0)
-                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
-                                     (this->mapping_collection,
-                                      *this->finite_elements[i],
-                                      quadrature,
-                                      this->update_flags));
-            }
-        }
-      else
-        {
-          dealii::hp::QCollection<dim-1>
-            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
-          x_fe_face_values.resize(this->finite_elements.size());
-          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
-            {
-              // check if there is a finite element that is equal to the
-              // present one, then we can re-use the FEValues object
-              for (unsigned int j=0; j<i; ++j)
-                if (this->finite_elements[i].get() ==
-                    this->finite_elements[j].get())
-                  {
-                    x_fe_face_values[i] = x_fe_face_values[j];
-                    break;
-                  }
-              if (x_fe_face_values[i].get() == 0)
-                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
-                                          (this->mapping_collection,
-                                           *this->finite_elements[i],
-                                           quadrature,
-                                           this->update_flags));
-            }
-        }
-    }
-
-
-
-    template <int dim, int spacedim>
-    template <typename DH>
-    void
-    ParallelDataBase<dim,spacedim>::
-    reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
-                         const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
-                         const unsigned int face)
-    {
-      for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
-        {
-          bool duplicate = false;
-          for (unsigned int j=0; j<dataset; ++j)
-            if (finite_elements[dataset].get() == finite_elements[j].get())
-              duplicate = true;
-          if (duplicate == false)
-            {
-              typename DH::active_cell_iterator dh_cell(&cell->get_triangulation(),
-                                                        cell->level(),
-                                                        cell->index(),
-                                                        dof_data[dataset]->dof_handler);
-              if (x_fe_values.empty())
-                {
-                  AssertIndexRange(face,
-                                   GeometryInfo<dim>::faces_per_cell);
-                  x_fe_face_values[dataset]->reinit(dh_cell, face);
-                }
-              else
-                x_fe_values[dataset]->reinit (dh_cell);
-            }
-        }
-      if (dof_data.empty())
-        {
-          if (x_fe_values.empty())
-            {
-              AssertIndexRange(face,
-                               GeometryInfo<dim>::faces_per_cell);
-              x_fe_face_values[0]->reinit(cell, face);
-            }
-          else
-            x_fe_values[0]->reinit (cell);
-        }
-    }
-
-
-
-    template <int dim, int spacedim>
-    const FEValuesBase<dim,spacedim> &
-    ParallelDataBase<dim,spacedim>::
-    get_present_fe_values(const unsigned int dataset) const
-    {
-      AssertIndexRange(dataset, finite_elements.size());
-      if (x_fe_values.empty())
-        return x_fe_face_values[dataset]->get_present_fe_values();
-      else
-        return x_fe_values[dataset]->get_present_fe_values();
-    }
-
-
-
-    template <int dim, int spacedim>
-    void
-    ParallelDataBase<dim,spacedim>::
-    resize_system_vectors(const unsigned int n_components)
-    {
-      Assert(patch_values_system.size() > 0, ExcInternalError());
-      AssertDimension(patch_values_system.size(),
-                      patch_gradients_system.size());
-      AssertDimension(patch_values_system.size(),
-                      patch_hessians_system.size());
-      if (patch_values_system[0].size() == n_components)
-        return;
-      for (unsigned int k=0; k<patch_values_system.size(); ++k)
-        {
-          patch_values_system[k].reinit(n_components);
-          patch_gradients_system[k].resize(n_components);
-          patch_hessians_system[k].resize(n_components);
-        }
-    }
-
-
-
-
     template <int dim, int spacedim>
     ParallelData<dim,spacedim>::
     ParallelData (const unsigned int n_datasets,
@@ -309,7 +58,6 @@ namespace internal
 
 
 
-
     /**
      * In a WorkStream context, use this function to append the patch computed
      * by the parallel stage to the array of patches.
@@ -326,845 +74,6 @@ namespace internal
 }
 
 
-namespace internal
-{
-  namespace DataOut
-  {
-    template <class DH>
-    DataEntryBase<DH>::DataEntryBase (const DH                       *dofs,
-                                      const std::vector<std::string> &names_in,
-                                      const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
-      :
-      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
-      names(names_in),
-      data_component_interpretation (data_component_interpretation),
-      postprocessor(0, typeid(*this).name()),
-      n_output_variables(names.size())
-    {
-      Assert (names.size() == data_component_interpretation.size(),
-              ExcDimensionMismatch(data_component_interpretation.size(),
-                                   names.size()));
-
-      // check that the names use only allowed characters
-      for (unsigned int i=0; i<names.size(); ++i)
-        Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
-                                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                           "0123456789_<>()") == std::string::npos,
-                typename dealii::DataOut<DH::dimension>::
-                ExcInvalidCharacter (names[i],
-                                     names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
-                                                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                                                "0123456789_<>()")));
-    }
-
-
-
-    template <class DH>
-    DataEntryBase<DH>::DataEntryBase (const DH *dofs,
-                                      const DataPostprocessor<DH::space_dimension> *data_postprocessor)
-      :
-      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
-      names(data_postprocessor->get_names()),
-      data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
-      postprocessor(data_postprocessor, typeid(*this).name()),
-      n_output_variables(names.size())
-    {
-      Assert (data_postprocessor->get_names().size()
-              ==
-              data_postprocessor->get_data_component_interpretation().size(),
-              ExcDimensionMismatch (data_postprocessor->get_names().size(),
-                                    data_postprocessor->get_data_component_interpretation().size()));
-
-      // check that the names use only allowed characters
-      for (unsigned int i=0; i<names.size(); ++i)
-        Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
-                                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                           "0123456789_<>()") == std::string::npos,
-                typename dealii::DataOut<DH::dimension>::
-                ExcInvalidCharacter (names[i],
-                                     names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
-                                                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                                                "0123456789_<>()")));
-    }
-
-
-
-    template <class DH>
-    DataEntryBase<DH>::~DataEntryBase ()
-    {}
-
-
-
-    /**
-     * Class that stores a pointer to a vector of type equal to the template
-     * argument, and provides the functions to extract data from it.
-     *
-     * @author Wolfgang Bangerth, 2004
-     */
-    template <class DH, typename VectorType>
-    class DataEntry : public DataEntryBase<DH>
-    {
-    public:
-      /**
-       * Constructor. Give a list of names for the individual components of
-       * the vector and their interpretation as scalar or vector data. This
-       * constructor assumes that no postprocessor is going to be used.
-       */
-      DataEntry (const DH                       *dofs,
-                 const VectorType               *data,
-                 const std::vector<std::string> &names,
-                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
-
-      /**
-       * Constructor when a data postprocessor is going to be used. In that
-       * case, the names and vector declarations are going to be acquired from
-       * the postprocessor.
-       */
-      DataEntry (const DH                                     *dofs,
-                 const VectorType                             *data,
-                 const DataPostprocessor<DH::space_dimension> *data_postprocessor);
-
-      /**
-       * Assuming that the stored vector is a cell vector, extract the given
-       * element from it.
-       */
-      virtual
-      double
-      get_cell_data_value (const unsigned int cell_number) const;
-
-      /**
-       * Given a FEValuesBase object, extract the values on the present cell
-       * from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<double>             &patch_values) const;
-
-      /**
-       * Given a FEValuesBase object, extract the values on the present cell
-       * from the vector we actually store. This function does the same as the
-       * one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<dealii::Vector<double> >    &patch_values_system) const;
-
-      /**
-       * Given a FEValuesBase object, extract the gradients on the present
-       * cell from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                              std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const;
-
-      /**
-       * Given a FEValuesBase object, extract the gradients on the present
-       * cell from the vector we actually store. This function does the same
-       * as the one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                              std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
-
-      /**
-       * Given a FEValuesBase object, extract the second derivatives on the
-       * present cell from the vector we actually store.
-       */
-      virtual
-      void
-      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                             std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const;
-
-      /**
-       * Given a FEValuesBase object, extract the second derivatives on the
-       * present cell from the vector we actually store. This function does
-       * the same as the one above but for vector-valued finite elements.
-       */
-      virtual
-      void
-      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                             std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
-
-      /**
-       * Clear all references to the vectors.
-       */
-      virtual void clear ();
-
-      /**
-       * Determine an estimate for the memory consumption (in bytes) of this
-       * object.
-       */
-      virtual std::size_t memory_consumption () const;
-
-    private:
-      /**
-       * Pointer to the data vector. Note that ownership of the vector pointed
-       * to remains with the caller of this class.
-       */
-      const VectorType *vector;
-    };
-
-
-
-    template <class DH, class VectorType>
-    DataEntry<DH,VectorType>::
-    DataEntry (const DH                               *dofs,
-               const VectorType                       *data,
-               const std::vector<std::string>         &names,
-               const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
-      :
-      DataEntryBase<DH> (dofs, names, data_component_interpretation),
-      vector (data)
-    {}
-
-
-
-    template <class DH, class VectorType>
-    DataEntry<DH,VectorType>::
-    DataEntry (const DH                                     *dofs,
-               const VectorType                             *data,
-               const DataPostprocessor<DH::space_dimension> *data_postprocessor)
-      :
-      DataEntryBase<DH> (dofs, data_postprocessor),
-      vector (data)
-    {}
-
-
-    namespace
-    {
-      template <class VectorType>
-      double
-      get_vector_element (const VectorType &vector,
-                          const unsigned int cell_number)
-      {
-        return vector[cell_number];
-      }
-
-
-      double
-      get_vector_element (const IndexSet &is,
-                          const unsigned int cell_number)
-      {
-        return (is.is_element(cell_number) ? 1 : 0);
-      }
-    }
-
-
-
-    template <class DH, class VectorType>
-    double
-    DataEntry<DH,VectorType>::
-    get_cell_data_value (const unsigned int cell_number) const
-    {
-      return get_vector_element(*vector, cell_number);
-    }
-
-
-
-    template <class DH, class VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                         std::vector<dealii::Vector<double> >    &patch_values_system) const
-    {
-      fe_patch_values.get_function_values (*vector, patch_values_system);
-    }
-
-
-
-    template <class DH, typename VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                         std::vector<double>             &patch_values) const
-    {
-      fe_patch_values.get_function_values (*vector, patch_values);
-    }
-
-
-
-    template <class DH, class VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                            std::vector<std::vector<Tensor<1,DH::space_dimension> > >   &patch_gradients_system) const
-    {
-      fe_patch_values.get_function_gradients (*vector, patch_gradients_system);
-    }
-
-
-
-    template <class DH, typename VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                            std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const
-    {
-      fe_patch_values.get_function_gradients (*vector, patch_gradients);
-    }
-
-
-
-    template <class DH, class VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<std::vector<Tensor<2,DH::space_dimension> > >   &patch_hessians_system) const
-    {
-      fe_patch_values.get_function_hessians (*vector, patch_hessians_system);
-    }
-
-
-
-    template <class DH, typename VectorType>
-    void
-    DataEntry<DH,VectorType>::
-    get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
-                           std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const
-    {
-      fe_patch_values.get_function_hessians (*vector, patch_hessians);
-    }
-
-
-
-    template <class DH, typename VectorType>
-    std::size_t
-    DataEntry<DH,VectorType>::memory_consumption () const
-    {
-      return (sizeof (vector) +
-              MemoryConsumption::memory_consumption (this->names));
-    }
-
-
-
-    template <class DH, class VectorType>
-    void
-    DataEntry<DH,VectorType>::clear ()
-    {
-      vector = 0;
-      this->dof_handler = 0;
-    }
-  }
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::DataOut_DoFData ()
-  :
-  triangulation(0,typeid(*this).name()),
-  dofs(0,typeid(*this).name())
-{}
-
-
-
-template <class DH, int patch_dim, int patch_space_dim>
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::~DataOut_DoFData ()
-{
-  clear ();
-}
-
-
-
-template <class DH, int patch_dim, int patch_space_dim>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-attach_dof_handler (const DH &d)
-{
-  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
-  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
-
-  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&d.get_tria(), typeid(*this).name());
-  dofs = SmartPointer<const DH>(&d, typeid(*this).name());
-}
-
-
-
-template <class DH, int patch_dim, int patch_space_dim>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-attach_triangulation (const Triangulation<DH::dimension,DH::space_dimension> &tria)
-{
-  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
-  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
-
-  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&tria, typeid(*this).name());
-}
-
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const VECTOR                             &vec,
-                 const std::string                        &name,
-                 const DataVectorType                      type,
-                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
-{
-  Assert (triangulation != 0, ExcNoTriangulationSelected ());
-  const unsigned int n_components =
-    dofs != 0 ? dofs->get_fe().n_components () : 1;
-
-  std::vector<std::string> names;
-  // if only one component or vector is cell vector: we only need one name
-  if ((n_components == 1) ||
-      (vec.size() == triangulation->n_active_cells()))
-    {
-      names.resize (1, name);
-    }
-  else
-    // otherwise append _i to the given name
-    {
-      names.resize (n_components);
-      for (unsigned int i=0; i<n_components; ++i)
-        {
-          std::ostringstream namebuf;
-          namebuf << '_' << i;
-          names[i] = name + namebuf.str();
-        }
-    }
-
-  add_data_vector (vec, names, type, data_component_interpretation);
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const VECTOR                             &vec,
-                 const std::vector<std::string>           &names,
-                 const DataVectorType                      type,
-                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
-{
-  Assert (triangulation != 0, ExcNoTriangulationSelected ());
-
-  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
-  data_component_interpretation
-    = (data_component_interpretation_.size() != 0
-       ?
-       data_component_interpretation_
-       :
-       std::vector<DataComponentInterpretation::DataComponentInterpretation>
-       (names.size(), DataComponentInterpretation::component_is_scalar));
-
-  // either cell data and one name,
-  // or dof data and n_components names
-  DataVectorType actual_type = type;
-  if (type == type_automatic)
-    {
-      if (vec.size() == triangulation->n_active_cells())
-        actual_type = type_cell_data;
-      else
-        actual_type = type_dof_data;
-    }
-
-  switch (actual_type)
-    {
-    case type_cell_data:
-      Assert (vec.size() == triangulation->n_active_cells(),
-              ExcDimensionMismatch (vec.size(),
-                                    triangulation->n_active_cells()));
-      Assert (names.size() == 1,
-              ExcInvalidNumberOfNames (names.size(), 1));
-      break;
-
-    case type_dof_data:
-      Assert (dofs != 0, ExcNoDoFHandlerSelected ());
-      Assert (vec.size() == dofs->n_dofs(),
-              ExcInvalidVectorSize (vec.size(),
-                                    dofs->n_dofs(),
-                                    triangulation->n_active_cells()));
-      Assert (names.size() == dofs->get_fe().n_components(),
-              ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
-      break;
-
-    case type_automatic:
-      // this case should have been handled above...
-      Assert (false, ExcInternalError());
-    }
-
-  internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, names,
-                                                  data_component_interpretation);
-  if (actual_type == type_dof_data)
-    dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
-  else
-    cell_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const VECTOR                           &vec,
-                 const DataPostprocessor<DH::space_dimension> &data_postprocessor)
-{
-  // this is a specialized version of the other function where we have a
-  // postprocessor. if we do, we know that we have type_dof_data, which makes
-  // things a bit simpler, we also don't need to deal with some of the other
-  // stuff and use a different constructor of DataEntry
-
-  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
-
-  Assert (vec.size() == dofs->n_dofs(),
-          ExcInvalidVectorSize (vec.size(),
-                                dofs->n_dofs(),
-                                dofs->get_tria().n_active_cells()));
-
-  internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, &data_postprocessor);
-  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const DH                               &dof_handler,
-                 const VECTOR                           &vec,
-                 const DataPostprocessor<DH::space_dimension> &data_postprocessor)
-{
-  // this is a specialized version of the other function where we have a
-  // postprocessor. if we do, we know that we have type_dof_data, which makes
-  // things a bit simpler, we also don't need to deal with some of the other
-  // stuff and use a different constructor of DataEntry
-
-  AssertDimension (vec.size(), dof_handler.n_dofs());
-
-  internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &vec, &data_postprocessor);
-  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const DH                       &dof_handler,
-                 const VECTOR                   &data,
-                 const std::string              &name,
-                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
-{
-  const unsigned int n_components = dof_handler.get_fe().n_components ();
-
-  std::vector<std::string> names;
-  // if only one component: we only need one name
-  if (n_components == 1)
-    names.resize (1, name);
-  else
-    // otherwise append _i to the given name
-    {
-      names.resize (n_components);
-      for (unsigned int i=0; i<n_components; ++i)
-        {
-          std::ostringstream namebuf;
-          namebuf << '_' << i;
-          names[i] = name + namebuf.str();
-        }
-    }
-
-  add_data_vector (dof_handler, data, names, data_component_interpretation);
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-template <class VECTOR>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-add_data_vector (const DH                       &dof_handler,
-                 const VECTOR                   &data,
-                 const std::vector<std::string> &names,
-                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
-{
-  // this is an extended version of the other functions where we pass a vector
-  // together with its DoFHandler. if we do, we know that we have
-  // type_dof_data, which makes things a bit simpler
-  if (triangulation == 0)
-    triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&dof_handler.get_tria(), typeid(*this).name());
-
-  Assert (&dof_handler.get_tria() == triangulation,
-          ExcMessage("The triangulation attached to the DoFHandler does not "
-                     "match with the one set previously"));
-
-  Assert (data.size() == dof_handler.n_dofs(),
-          ExcDimensionMismatch (data.size(), dof_handler.n_dofs()));
-
-  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
-  data_component_interpretation
-    = (data_component_interpretation_.size() != 0
-       ?
-       data_component_interpretation_
-       :
-       std::vector<DataComponentInterpretation::DataComponentInterpretation>
-       (names.size(), DataComponentInterpretation::component_is_scalar));
-
-  internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &data, names,
-                                                  data_component_interpretation);
-  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-void DataOut_DoFData<DH,patch_dim,patch_space_dim>::clear_data_vectors ()
-{
-  dof_data.erase (dof_data.begin(), dof_data.end());
-  cell_data.erase (cell_data.begin(), cell_data.end());
-
-  // delete patches
-  std::vector<Patch> dummy;
-  patches.swap (dummy);
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-clear_input_data_references ()
-{
-  for (unsigned int i=0; i<dof_data.size(); ++i)
-    dof_data[i]->clear ();
-
-  for (unsigned int i=0; i<cell_data.size(); ++i)
-    cell_data[i]->clear ();
-
-  if (dofs != 0)
-    dofs = 0;
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-void
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::clear ()
-{
-  dof_data.erase (dof_data.begin(), dof_data.end());
-  cell_data.erase (cell_data.begin(), cell_data.end());
-
-  if (dofs != 0)
-    dofs = 0;
-
-  // delete patches
-  std::vector<Patch> dummy;
-  patches.swap (dummy);
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-std::vector<std::string>
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::
-get_dataset_names () const
-{
-  std::vector<std::string> names;
-  // collect the names of dof
-  // and cell data
-  typedef
-  typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
-  data_iterator;
-
-  for (data_iterator  d=dof_data.begin();
-       d!=dof_data.end(); ++d)
-    for (unsigned int i=0; i<(*d)->names.size(); ++i)
-      names.push_back ((*d)->names[i]);
-  for (data_iterator d=cell_data.begin(); d!=cell_data.end(); ++d)
-    {
-      Assert ((*d)->names.size() == 1, ExcInternalError());
-      names.push_back ((*d)->names[0]);
-    }
-
-  return names;
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_vector_data_ranges () const
-{
-  std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
-  ranges;
-
-  // collect the ranges of dof
-  // and cell data
-  typedef
-  typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
-  data_iterator;
-
-  unsigned int output_component = 0;
-  for (data_iterator  d=dof_data.begin();
-       d!=dof_data.end(); ++d)
-    for (unsigned int i=0; i<(*d)->n_output_variables;
-         ++i, ++output_component)
-      // see what kind of data we have
-      // here. note that for the purpose of
-      // the current function all we care
-      // about is vector data
-      if ((*d)->data_component_interpretation[i] ==
-          DataComponentInterpretation::component_is_part_of_vector)
-        {
-          // ensure that there is a
-          // continuous number of next
-          // space_dim components that all
-          // deal with vectors
-          Assert (i+patch_space_dim <=
-                  (*d)->n_output_variables,
-                  ExcInvalidVectorDeclaration (i,
-                                               (*d)->names[i]));
-          for (unsigned int dd=1; dd<patch_space_dim; ++dd)
-            Assert ((*d)->data_component_interpretation[i+dd]
-                    ==
-                    DataComponentInterpretation::component_is_part_of_vector,
-                    ExcInvalidVectorDeclaration (i,
-                                                 (*d)->names[i]));
-
-          // all seems alright, so figure out
-          // whether there is a common name
-          // to these components. if not,
-          // leave the name empty and let the
-          // output format writer decide what
-          // to do here
-          std::string name = (*d)->names[i];
-          for (unsigned int dd=1; dd<patch_space_dim; ++dd)
-            if (name != (*d)->names[i+dd])
-              {
-                name = "";
-                break;
-              }
-
-          // finally add a corresponding
-          // range
-          std_cxx1x::tuple<unsigned int, unsigned int, std::string>
-          range (output_component,
-                 output_component+patch_space_dim-1,
-                 name);
-
-          ranges.push_back (range);
-
-          // increase the 'component' counter
-          // by the appropriate amount, same
-          // for 'i', since we have already
-          // dealt with all these components
-          output_component += patch_space_dim-1;
-          i += patch_space_dim-1;
-        }
-
-  // note that we do not have to traverse the
-  // list of cell data here because cell data
-  // is one value per (logical) cell and
-  // therefore cannot be a vector
-
-  // as a final check, the 'component'
-  // counter should be at the total number of
-  // components added up now
-#ifdef DEBUG
-  unsigned int n_output_components = 0;
-  for (data_iterator  d=dof_data.begin();
-       d!=dof_data.end(); ++d)
-    n_output_components += (*d)->n_output_variables;
-  Assert (output_component == n_output_components,
-          ExcInternalError());
-#endif
-
-  return ranges;
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-const std::vector< dealii::DataOutBase::Patch<patch_dim, patch_space_dim> > &
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_patches () const
-{
-  return patches;
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_finite_elements() const
-{
-  const unsigned int dhdim = DH::dimension;
-  const unsigned int dhspacedim = DH::space_dimension;
-  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dhdim,dhspacedim> > >
-    finite_elements(this->dof_data.size());
-  for (unsigned int i=0; i<this->dof_data.size(); ++i)
-    {
-      Assert (dof_data[i]->dof_handler != 0, ExcNoDoFHandlerSelected ());
-
-      // avoid creating too many finite elements and doing a lot of work on
-      // initializing FEValues downstream: if two DoFHandlers are the same
-      // (checked by pointer comparison), we can re-use the shared_ptr object
-      // for the second one. We cannot check for finite element equalities
-      // because we need different FEValues objects for different dof
-      // handlers.
-      bool duplicate = false;
-      for (unsigned int j=0; j<i; ++j)
-        if (dof_data[i]->dof_handler == dof_data[j]->dof_handler)
-          {
-            finite_elements[i] = finite_elements[j];
-            duplicate = true;
-          }
-      if (duplicate == false)
-        finite_elements[i].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
-                                 (this->dof_data[i]->dof_handler->get_fe()));
-    }
-  if (this->dof_data.empty())
-    {
-      finite_elements.resize(1);
-      finite_elements[0].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
-                               (FE_DGQ<dhdim,dhspacedim>(0)));
-    }
-  return finite_elements;
-}
-
-
-
-template <class DH,
-         int patch_dim, int patch_space_dim>
-std::size_t
-DataOut_DoFData<DH,patch_dim,patch_space_dim>::memory_consumption () const
-{
-  return (DataOutInterface<patch_dim,patch_space_dim>::memory_consumption () +
-          MemoryConsumption::memory_consumption (dofs) +
-          MemoryConsumption::memory_consumption (patches));
-}
-
-
-
-/* ---------------------------------------------------------------------- */
-
 
 template <int dim, class DH>
 void
index aa157920a15b9e3e973b18a45785b8191d40d485..07355823c9e1a4989070f2c467405e0f615bc33d 100644 (file)
 // ---------------------------------------------------------------------
 
 
-for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
-{
-// codim=0
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC            &,
-                        const std::string   &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                       &,
-                        const std::vector<std::string> &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                 &,
-                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-
-
-// stuff needed for face data
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const VEC                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC            &,
-                        const std::string   &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                       &,
-                        const std::vector<std::string> &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                 &,
-                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-
-
-// things for DataOutRotation
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC            &,
-                        const std::string   &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                       &,
-                        const std::vector<std::string> &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
-                        const VEC                 &,
-                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
 
-
-// codim 1
-
-  #if deal_II_dimension < 3
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const VEC                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
-                        const VEC            &,
-                        const std::string   &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
-                        const VEC                       &,
-                        const std::vector<std::string> &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
-                        const VEC                 &,
-                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
-  #endif
-
-
-
-// codim 2
-
-  #if deal_II_dimension == 3
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const VEC            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const VEC                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const VEC                 &,
-                      const DataPostprocessor<DH<1,3>::space_dimension> &);
-
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const DH<1,3> &,
-                        const VEC            &,
-                        const std::string   &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const DH<1,3> &,
-                        const VEC                       &,
-                        const std::vector<std::string> &,
-                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<1,3>,1,3>::
-  add_data_vector<VEC> (const DH<1,3> &,
-                        const VEC                 &,
-                        const DataPostprocessor<DH<1,3>::space_dimension> &);
-  #endif
-
-}
-
-
-
-for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
 {
-// codim=0
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-// stuff needed for face data
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
-  add_data_vector<IndexSet> (const IndexSet                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-// things for DataOutRotation
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
-
-// codim 1
-
-  #if deal_II_dimension < 3
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet            &,
-                       const std::string   &,
-                       const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet                       &,
-                     const std::vector<std::string> &,
-                     const DataVectorType,
-                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
-
-  template void
-  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
-  add_data_vector<IndexSet> (const IndexSet                 &,
-                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
-  #endif
-
+  namespace internal \{
+    namespace DataOut \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template struct ParallelData<deal_II_dimension,deal_II_space_dimension>;
+#endif
+    \}
+  \}
 }
 
 
-
 for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
 {
   template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension>;
@@ -340,9 +38,6 @@ for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
   template class DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>;
   #endif
 
-  #if deal_II_dimension >= 2
-  template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>;
-  #endif
 
   template class DataOut<deal_II_dimension, DH<deal_II_dimension> >;
   #if deal_II_dimension < 3
@@ -350,40 +45,6 @@ for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
   #endif
 
   #if deal_II_dimension == 3
-     template class DataOut_DoFData<DH<1>,1,3>;
-     template class DataOut_DoFData<DH<1,3>,1,3>;
      template class DataOut<1, DH<1,3> >;
   #endif
-
-}
-
-
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
-{
-  namespace internal \{
-    namespace DataOut \{
-#if deal_II_dimension <= deal_II_space_dimension
-      template struct ParallelDataBase<deal_II_dimension,deal_II_space_dimension>;
-      template struct ParallelData<deal_II_dimension,deal_II_space_dimension>;
-#endif
-    \}
-  \}
-}
-
-
-for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
-{
-  namespace internal \{
-    namespace DataOut \{
-#if deal_II_dimension <= deal_II_space_dimension
-      template
-      void 
-      ParallelDataBase<deal_II_dimension,deal_II_space_dimension>::
-      reinit_all_fe_values<dealii::DH<deal_II_dimension,deal_II_space_dimension> >
-      (std::vector<std_cxx1x::shared_ptr<DataEntryBase<dealii::DH<deal_II_dimension,deal_II_space_dimension> > > > &dof_data,
-       const dealii::Triangulation<deal_II_dimension,deal_II_space_dimension>::cell_iterator &cell,
-       const unsigned int face);
-#endif
-    \}
-  \}
-}
+}
\ No newline at end of file
diff --git a/deal.II/source/numerics/data_out_dof_data.cc b/deal.II/source/numerics/data_out_dof_data.cc
new file mode 100644 (file)
index 0000000..37ff85b
--- /dev/null
@@ -0,0 +1,1146 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1999 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/work_stream.h>
+#include <deal.II/base/memory_consumption.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/block_vector.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
+#include <deal.II/lac/petsc_vector.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/numerics/data_out.h>
+#include <deal.II/numerics/data_out_dof_data.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/hp/dof_handler.h>
+#include <deal.II/hp/fe_values.h>
+#include <deal.II/fe/mapping_q1.h>
+
+#include <sstream>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+namespace internal
+{
+  namespace DataOut
+  {
+    template <int dim, int spacedim>
+    ParallelDataBase<dim,spacedim>::
+    ParallelDataBase (const unsigned int n_datasets,
+                      const unsigned int n_subdivisions,
+                      const std::vector<unsigned int> &n_postprocessor_outputs,
+                      const Mapping<dim,spacedim> &mapping,
+                      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                      const UpdateFlags update_flags,
+                      const bool        use_face_values)
+      :
+      n_datasets (n_datasets),
+      n_subdivisions (n_subdivisions),
+      postprocessed_values (n_postprocessor_outputs.size()),
+      mapping_collection (mapping),
+      finite_elements (finite_elements),
+      update_flags (update_flags)
+    {
+      unsigned int n_q_points = 0;
+      if (use_face_values == false)
+        {
+          dealii::hp::QCollection<dim>
+            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
+          n_q_points = quadrature[0].size();
+          x_fe_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_values[i] = x_fe_values[j];
+                    break;
+                  }
+              if (x_fe_values[i].get() == 0)
+                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
+                                     (this->mapping_collection,
+                                      *this->finite_elements[i],
+                                      quadrature,
+                                      this->update_flags));
+            }
+        }
+      else
+        {
+          dealii::hp::QCollection<dim-1>
+            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
+          n_q_points = quadrature[0].size();
+          x_fe_face_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_face_values[i] = x_fe_face_values[j];
+                    break;
+                  }
+              if (x_fe_face_values[i].get() == 0)
+                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
+                                          (this->mapping_collection,
+                                           *this->finite_elements[i],
+                                           quadrature,
+                                           this->update_flags));
+            }
+        }
+
+      patch_values.resize (n_q_points);
+      patch_values_system.resize (n_q_points);
+      patch_gradients.resize (n_q_points);
+      patch_gradients_system.resize (n_q_points);
+      patch_hessians.resize (n_q_points);
+      patch_hessians_system.resize (n_q_points);
+
+      for (unsigned int dataset=0; dataset<n_postprocessor_outputs.size(); ++dataset)
+        if (n_postprocessor_outputs[dataset] != 0)
+          postprocessed_values[dataset]
+          .resize(n_q_points,
+                  dealii::Vector<double>(n_postprocessor_outputs[dataset]));
+    }
+
+
+
+
+
+    // implement copy constructor to create a thread's own version of
+    // x_fe_values
+    template <int dim, int spacedim>
+    ParallelDataBase<dim,spacedim>::
+    ParallelDataBase (const ParallelDataBase<dim,spacedim> &data)
+      :
+      n_datasets (data.n_datasets),
+      n_subdivisions (data.n_subdivisions),
+      patch_values (data.patch_values),
+      patch_values_system (data.patch_values_system),
+      patch_gradients (data.patch_gradients),
+      patch_gradients_system (data.patch_gradients_system),
+      patch_hessians (data.patch_hessians),
+      patch_hessians_system (data.patch_hessians_system),
+      postprocessed_values (data.postprocessed_values),
+      mapping_collection (data.mapping_collection),
+      finite_elements (data.finite_elements),
+      update_flags (data.update_flags)
+    {
+      if (data.x_fe_values.empty() == false)
+        {
+          Assert(data.x_fe_face_values.empty() == true, ExcInternalError());
+          dealii::hp::QCollection<dim>
+            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
+          x_fe_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_values[i] = x_fe_values[j];
+                    break;
+                  }
+              if (x_fe_values[i].get() == 0)
+                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
+                                     (this->mapping_collection,
+                                      *this->finite_elements[i],
+                                      quadrature,
+                                      this->update_flags));
+            }
+        }
+      else
+        {
+          dealii::hp::QCollection<dim-1>
+            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
+          x_fe_face_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_face_values[i] = x_fe_face_values[j];
+                    break;
+                  }
+              if (x_fe_face_values[i].get() == 0)
+                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
+                                          (this->mapping_collection,
+                                           *this->finite_elements[i],
+                                           quadrature,
+                                           this->update_flags));
+            }
+        }
+    }
+
+
+
+    template <int dim, int spacedim>
+    template <typename DH>
+    void
+    ParallelDataBase<dim,spacedim>::
+    reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
+                         const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
+                         const unsigned int face)
+    {
+      for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
+        {
+          bool duplicate = false;
+          for (unsigned int j=0; j<dataset; ++j)
+            if (finite_elements[dataset].get() == finite_elements[j].get())
+              duplicate = true;
+          if (duplicate == false)
+            {
+              typename DH::active_cell_iterator dh_cell(&cell->get_triangulation(),
+                                                        cell->level(),
+                                                        cell->index(),
+                                                        dof_data[dataset]->dof_handler);
+              if (x_fe_values.empty())
+                {
+                  AssertIndexRange(face,
+                                   GeometryInfo<dim>::faces_per_cell);
+                  x_fe_face_values[dataset]->reinit(dh_cell, face);
+                }
+              else
+                x_fe_values[dataset]->reinit (dh_cell);
+            }
+        }
+      if (dof_data.empty())
+        {
+          if (x_fe_values.empty())
+            {
+              AssertIndexRange(face,
+                               GeometryInfo<dim>::faces_per_cell);
+              x_fe_face_values[0]->reinit(cell, face);
+            }
+          else
+            x_fe_values[0]->reinit (cell);
+        }
+    }
+
+
+
+    template <int dim, int spacedim>
+    const FEValuesBase<dim,spacedim> &
+    ParallelDataBase<dim,spacedim>::
+    get_present_fe_values(const unsigned int dataset) const
+    {
+      AssertIndexRange(dataset, finite_elements.size());
+      if (x_fe_values.empty())
+        return x_fe_face_values[dataset]->get_present_fe_values();
+      else
+        return x_fe_values[dataset]->get_present_fe_values();
+    }
+
+
+
+    template <int dim, int spacedim>
+    void
+    ParallelDataBase<dim,spacedim>::
+    resize_system_vectors(const unsigned int n_components)
+    {
+      Assert(patch_values_system.size() > 0, ExcInternalError());
+      AssertDimension(patch_values_system.size(),
+                      patch_gradients_system.size());
+      AssertDimension(patch_values_system.size(),
+                      patch_hessians_system.size());
+      if (patch_values_system[0].size() == n_components)
+        return;
+      for (unsigned int k=0; k<patch_values_system.size(); ++k)
+        {
+          patch_values_system[k].reinit(n_components);
+          patch_gradients_system[k].resize(n_components);
+          patch_hessians_system[k].resize(n_components);
+        }
+    }
+
+
+
+
+    /**
+     * In a WorkStream context, use this function to append the patch computed
+     * by the parallel stage to the array of patches.
+     */
+    template <int dim, int spacedim>
+    void
+    append_patch_to_list (const DataOutBase::Patch<dim,spacedim> &patch,
+                          std::vector<DataOutBase::Patch<dim,spacedim> > &patches)
+    {
+      patches.push_back (patch);
+      patches.back().patch_index = patches.size()-1;
+    }
+  }
+}
+
+namespace internal
+{
+  namespace DataOut
+  {
+    template <class DH>
+    DataEntryBase<DH>::DataEntryBase (const DH                       *dofs,
+                                      const std::vector<std::string> &names_in,
+                                      const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+      :
+      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
+      names(names_in),
+      data_component_interpretation (data_component_interpretation),
+      postprocessor(0, typeid(*this).name()),
+      n_output_variables(names.size())
+    {
+      Assert (names.size() == data_component_interpretation.size(),
+              ExcDimensionMismatch(data_component_interpretation.size(),
+                                   names.size()));
+
+      // check that the names use only allowed characters
+      for (unsigned int i=0; i<names.size(); ++i)
+        Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                           "0123456789_<>()") == std::string::npos,
+                typename dealii::DataOut<DH::dimension>::
+                ExcInvalidCharacter (names[i],
+                                     names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                                                "0123456789_<>()")));
+    }
+
+
+
+    template <class DH>
+    DataEntryBase<DH>::DataEntryBase (const DH *dofs,
+                                      const DataPostprocessor<DH::space_dimension> *data_postprocessor)
+      :
+      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
+      names(data_postprocessor->get_names()),
+      data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
+      postprocessor(data_postprocessor, typeid(*this).name()),
+      n_output_variables(names.size())
+    {
+      Assert (data_postprocessor->get_names().size()
+              ==
+              data_postprocessor->get_data_component_interpretation().size(),
+              ExcDimensionMismatch (data_postprocessor->get_names().size(),
+                                    data_postprocessor->get_data_component_interpretation().size()));
+
+      // check that the names use only allowed characters
+      for (unsigned int i=0; i<names.size(); ++i)
+        Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                           "0123456789_<>()") == std::string::npos,
+                typename dealii::DataOut<DH::dimension>::
+                ExcInvalidCharacter (names[i],
+                                     names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                                                "0123456789_<>()")));
+    }
+
+
+
+    template <class DH>
+    DataEntryBase<DH>::~DataEntryBase ()
+    {}
+
+
+
+    /**
+     * Class that stores a pointer to a vector of type equal to the template
+     * argument, and provides the functions to extract data from it.
+     *
+     * @author Wolfgang Bangerth, 2004
+     */
+    template <class DH, typename VectorType>
+    class DataEntry : public DataEntryBase<DH>
+    {
+    public:
+      /**
+       * Constructor. Give a list of names for the individual components of
+       * the vector and their interpretation as scalar or vector data. This
+       * constructor assumes that no postprocessor is going to be used.
+       */
+      DataEntry (const DH                       *dofs,
+                 const VectorType               *data,
+                 const std::vector<std::string> &names,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
+
+      /**
+       * Constructor when a data postprocessor is going to be used. In that
+       * case, the names and vector declarations are going to be acquired from
+       * the postprocessor.
+       */
+      DataEntry (const DH                                     *dofs,
+                 const VectorType                             *data,
+                 const DataPostprocessor<DH::space_dimension> *data_postprocessor);
+
+      /**
+       * Assuming that the stored vector is a cell vector, extract the given
+       * element from it.
+       */
+      virtual
+      double
+      get_cell_data_value (const unsigned int cell_number) const;
+
+      /**
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<double>             &patch_values) const;
+
+      /**
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store. This function does the same as the
+       * one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<dealii::Vector<double> >    &patch_values_system) const;
+
+      /**
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const;
+
+      /**
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store. This function does the same
+       * as the one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                              std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
+
+      /**
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store.
+       */
+      virtual
+      void
+      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                             std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const;
+
+      /**
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store. This function does
+       * the same as the one above but for vector-valued finite elements.
+       */
+      virtual
+      void
+      get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                             std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
+
+      /**
+       * Clear all references to the vectors.
+       */
+      virtual void clear ();
+
+      /**
+       * Determine an estimate for the memory consumption (in bytes) of this
+       * object.
+       */
+      virtual std::size_t memory_consumption () const;
+
+    private:
+      /**
+       * Pointer to the data vector. Note that ownership of the vector pointed
+       * to remains with the caller of this class.
+       */
+      const VectorType *vector;
+    };
+
+
+
+    template <class DH, class VectorType>
+    DataEntry<DH,VectorType>::
+    DataEntry (const DH                               *dofs,
+               const VectorType                       *data,
+               const std::vector<std::string>         &names,
+               const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+      :
+      DataEntryBase<DH> (dofs, names, data_component_interpretation),
+      vector (data)
+    {}
+
+
+
+    template <class DH, class VectorType>
+    DataEntry<DH,VectorType>::
+    DataEntry (const DH                                     *dofs,
+               const VectorType                             *data,
+               const DataPostprocessor<DH::space_dimension> *data_postprocessor)
+      :
+      DataEntryBase<DH> (dofs, data_postprocessor),
+      vector (data)
+    {}
+
+
+    namespace
+    {
+      template <class VectorType>
+      double
+      get_vector_element (const VectorType &vector,
+                          const unsigned int cell_number)
+      {
+        return vector[cell_number];
+      }
+
+
+      double
+      get_vector_element (const IndexSet &is,
+                          const unsigned int cell_number)
+      {
+        return (is.is_element(cell_number) ? 1 : 0);
+      }
+    }
+
+
+
+    template <class DH, class VectorType>
+    double
+    DataEntry<DH,VectorType>::
+    get_cell_data_value (const unsigned int cell_number) const
+    {
+      return get_vector_element(*vector, cell_number);
+    }
+
+
+
+    template <class DH, class VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                         std::vector<dealii::Vector<double> >    &patch_values_system) const
+    {
+      fe_patch_values.get_function_values (*vector, patch_values_system);
+    }
+
+
+
+    template <class DH, typename VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                         std::vector<double>             &patch_values) const
+    {
+      fe_patch_values.get_function_values (*vector, patch_values);
+    }
+
+
+
+    template <class DH, class VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                            std::vector<std::vector<Tensor<1,DH::space_dimension> > >   &patch_gradients_system) const
+    {
+      fe_patch_values.get_function_gradients (*vector, patch_gradients_system);
+    }
+
+
+
+    template <class DH, typename VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                            std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const
+    {
+      fe_patch_values.get_function_gradients (*vector, patch_gradients);
+    }
+
+
+
+    template <class DH, class VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<std::vector<Tensor<2,DH::space_dimension> > >   &patch_hessians_system) const
+    {
+      fe_patch_values.get_function_hessians (*vector, patch_hessians_system);
+    }
+
+
+
+    template <class DH, typename VectorType>
+    void
+    DataEntry<DH,VectorType>::
+    get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
+                           std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const
+    {
+      fe_patch_values.get_function_hessians (*vector, patch_hessians);
+    }
+
+
+
+    template <class DH, typename VectorType>
+    std::size_t
+    DataEntry<DH,VectorType>::memory_consumption () const
+    {
+      return (sizeof (vector) +
+              MemoryConsumption::memory_consumption (this->names));
+    }
+
+
+
+    template <class DH, class VectorType>
+    void
+    DataEntry<DH,VectorType>::clear ()
+    {
+      vector = 0;
+      this->dof_handler = 0;
+    }
+  }
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::DataOut_DoFData ()
+  :
+  triangulation(0,typeid(*this).name()),
+  dofs(0,typeid(*this).name())
+{}
+
+
+
+template <class DH, int patch_dim, int patch_space_dim>
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::~DataOut_DoFData ()
+{
+  clear ();
+}
+
+
+
+template <class DH, int patch_dim, int patch_space_dim>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+attach_dof_handler (const DH &d)
+{
+  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
+  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
+
+  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&d.get_tria(), typeid(*this).name());
+  dofs = SmartPointer<const DH>(&d, typeid(*this).name());
+}
+
+
+
+template <class DH, int patch_dim, int patch_space_dim>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+attach_triangulation (const Triangulation<DH::dimension,DH::space_dimension> &tria)
+{
+  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
+  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
+
+  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&tria, typeid(*this).name());
+}
+
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const VECTOR                             &vec,
+                 const std::string                        &name,
+                 const DataVectorType                      type,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+{
+  Assert (triangulation != 0, ExcNoTriangulationSelected ());
+  const unsigned int n_components =
+    dofs != 0 ? dofs->get_fe().n_components () : 1;
+
+  std::vector<std::string> names;
+  // if only one component or vector is cell vector: we only need one name
+  if ((n_components == 1) ||
+      (vec.size() == triangulation->n_active_cells()))
+    {
+      names.resize (1, name);
+    }
+  else
+    // otherwise append _i to the given name
+    {
+      names.resize (n_components);
+      for (unsigned int i=0; i<n_components; ++i)
+        {
+          std::ostringstream namebuf;
+          namebuf << '_' << i;
+          names[i] = name + namebuf.str();
+        }
+    }
+
+  add_data_vector (vec, names, type, data_component_interpretation);
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const VECTOR                             &vec,
+                 const std::vector<std::string>           &names,
+                 const DataVectorType                      type,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
+{
+  Assert (triangulation != 0, ExcNoTriangulationSelected ());
+
+  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
+  data_component_interpretation
+    = (data_component_interpretation_.size() != 0
+       ?
+       data_component_interpretation_
+       :
+       std::vector<DataComponentInterpretation::DataComponentInterpretation>
+       (names.size(), DataComponentInterpretation::component_is_scalar));
+
+  // either cell data and one name,
+  // or dof data and n_components names
+  DataVectorType actual_type = type;
+  if (type == type_automatic)
+    {
+      if (vec.size() == triangulation->n_active_cells())
+        actual_type = type_cell_data;
+      else
+        actual_type = type_dof_data;
+    }
+
+  switch (actual_type)
+    {
+    case type_cell_data:
+      Assert (vec.size() == triangulation->n_active_cells(),
+              ExcDimensionMismatch (vec.size(),
+                                    triangulation->n_active_cells()));
+      Assert (names.size() == 1,
+              ExcInvalidNumberOfNames (names.size(), 1));
+      break;
+
+    case type_dof_data:
+      Assert (dofs != 0, ExcNoDoFHandlerSelected ());
+      Assert (vec.size() == dofs->n_dofs(),
+              ExcInvalidVectorSize (vec.size(),
+                                    dofs->n_dofs(),
+                                    triangulation->n_active_cells()));
+      Assert (names.size() == dofs->get_fe().n_components(),
+              ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
+      break;
+
+    case type_automatic:
+      // this case should have been handled above...
+      Assert (false, ExcInternalError());
+    }
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, names,
+                                                  data_component_interpretation);
+  if (actual_type == type_dof_data)
+    dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+  else
+    cell_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const VECTOR                           &vec,
+                 const DataPostprocessor<DH::space_dimension> &data_postprocessor)
+{
+  // this is a specialized version of the other function where we have a
+  // postprocessor. if we do, we know that we have type_dof_data, which makes
+  // things a bit simpler, we also don't need to deal with some of the other
+  // stuff and use a different constructor of DataEntry
+
+  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
+
+  Assert (vec.size() == dofs->n_dofs(),
+          ExcInvalidVectorSize (vec.size(),
+                                dofs->n_dofs(),
+                                dofs->get_tria().n_active_cells()));
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, &data_postprocessor);
+  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                               &dof_handler,
+                 const VECTOR                           &vec,
+                 const DataPostprocessor<DH::space_dimension> &data_postprocessor)
+{
+  // this is a specialized version of the other function where we have a
+  // postprocessor. if we do, we know that we have type_dof_data, which makes
+  // things a bit simpler, we also don't need to deal with some of the other
+  // stuff and use a different constructor of DataEntry
+
+  AssertDimension (vec.size(), dof_handler.n_dofs());
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &vec, &data_postprocessor);
+  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                       &dof_handler,
+                 const VECTOR                   &data,
+                 const std::string              &name,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+{
+  const unsigned int n_components = dof_handler.get_fe().n_components ();
+
+  std::vector<std::string> names;
+  // if only one component: we only need one name
+  if (n_components == 1)
+    names.resize (1, name);
+  else
+    // otherwise append _i to the given name
+    {
+      names.resize (n_components);
+      for (unsigned int i=0; i<n_components; ++i)
+        {
+          std::ostringstream namebuf;
+          namebuf << '_' << i;
+          names[i] = name + namebuf.str();
+        }
+    }
+
+  add_data_vector (dof_handler, data, names, data_component_interpretation);
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                       &dof_handler,
+                 const VECTOR                   &data,
+                 const std::vector<std::string> &names,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
+{
+  // this is an extended version of the other functions where we pass a vector
+  // together with its DoFHandler. if we do, we know that we have
+  // type_dof_data, which makes things a bit simpler
+  if (triangulation == 0)
+    triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&dof_handler.get_tria(), typeid(*this).name());
+
+  Assert (&dof_handler.get_tria() == triangulation,
+          ExcMessage("The triangulation attached to the DoFHandler does not "
+                     "match with the one set previously"));
+
+  Assert (data.size() == dof_handler.n_dofs(),
+          ExcDimensionMismatch (data.size(), dof_handler.n_dofs()));
+
+  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
+  data_component_interpretation
+    = (data_component_interpretation_.size() != 0
+       ?
+       data_component_interpretation_
+       :
+       std::vector<DataComponentInterpretation::DataComponentInterpretation>
+       (names.size(), DataComponentInterpretation::component_is_scalar));
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &data, names,
+                                                  data_component_interpretation);
+  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+void DataOut_DoFData<DH,patch_dim,patch_space_dim>::clear_data_vectors ()
+{
+  dof_data.erase (dof_data.begin(), dof_data.end());
+  cell_data.erase (cell_data.begin(), cell_data.end());
+
+  // delete patches
+  std::vector<Patch> dummy;
+  patches.swap (dummy);
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+clear_input_data_references ()
+{
+  for (unsigned int i=0; i<dof_data.size(); ++i)
+    dof_data[i]->clear ();
+
+  for (unsigned int i=0; i<cell_data.size(); ++i)
+    cell_data[i]->clear ();
+
+  if (dofs != 0)
+    dofs = 0;
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::clear ()
+{
+  dof_data.erase (dof_data.begin(), dof_data.end());
+  cell_data.erase (cell_data.begin(), cell_data.end());
+
+  if (dofs != 0)
+    dofs = 0;
+
+  // delete patches
+  std::vector<Patch> dummy;
+  patches.swap (dummy);
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+std::vector<std::string>
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+get_dataset_names () const
+{
+  std::vector<std::string> names;
+  // collect the names of dof
+  // and cell data
+  typedef
+  typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
+  data_iterator;
+
+  for (data_iterator  d=dof_data.begin();
+       d!=dof_data.end(); ++d)
+    for (unsigned int i=0; i<(*d)->names.size(); ++i)
+      names.push_back ((*d)->names[i]);
+  for (data_iterator d=cell_data.begin(); d!=cell_data.end(); ++d)
+    {
+      Assert ((*d)->names.size() == 1, ExcInternalError());
+      names.push_back ((*d)->names[0]);
+    }
+
+  return names;
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_vector_data_ranges () const
+{
+  std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
+  ranges;
+
+  // collect the ranges of dof
+  // and cell data
+  typedef
+  typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
+  data_iterator;
+
+  unsigned int output_component = 0;
+  for (data_iterator  d=dof_data.begin();
+       d!=dof_data.end(); ++d)
+    for (unsigned int i=0; i<(*d)->n_output_variables;
+         ++i, ++output_component)
+      // see what kind of data we have
+      // here. note that for the purpose of
+      // the current function all we care
+      // about is vector data
+      if ((*d)->data_component_interpretation[i] ==
+          DataComponentInterpretation::component_is_part_of_vector)
+        {
+          // ensure that there is a
+          // continuous number of next
+          // space_dim components that all
+          // deal with vectors
+          Assert (i+patch_space_dim <=
+                  (*d)->n_output_variables,
+                  ExcInvalidVectorDeclaration (i,
+                                               (*d)->names[i]));
+          for (unsigned int dd=1; dd<patch_space_dim; ++dd)
+            Assert ((*d)->data_component_interpretation[i+dd]
+                    ==
+                    DataComponentInterpretation::component_is_part_of_vector,
+                    ExcInvalidVectorDeclaration (i,
+                                                 (*d)->names[i]));
+
+          // all seems alright, so figure out
+          // whether there is a common name
+          // to these components. if not,
+          // leave the name empty and let the
+          // output format writer decide what
+          // to do here
+          std::string name = (*d)->names[i];
+          for (unsigned int dd=1; dd<patch_space_dim; ++dd)
+            if (name != (*d)->names[i+dd])
+              {
+                name = "";
+                break;
+              }
+
+          // finally add a corresponding
+          // range
+          std_cxx1x::tuple<unsigned int, unsigned int, std::string>
+          range (output_component,
+                 output_component+patch_space_dim-1,
+                 name);
+
+          ranges.push_back (range);
+
+          // increase the 'component' counter
+          // by the appropriate amount, same
+          // for 'i', since we have already
+          // dealt with all these components
+          output_component += patch_space_dim-1;
+          i += patch_space_dim-1;
+        }
+
+  // note that we do not have to traverse the
+  // list of cell data here because cell data
+  // is one value per (logical) cell and
+  // therefore cannot be a vector
+
+  // as a final check, the 'component'
+  // counter should be at the total number of
+  // components added up now
+#ifdef DEBUG
+  unsigned int n_output_components = 0;
+  for (data_iterator  d=dof_data.begin();
+       d!=dof_data.end(); ++d)
+    n_output_components += (*d)->n_output_variables;
+  Assert (output_component == n_output_components,
+          ExcInternalError());
+#endif
+
+  return ranges;
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+const std::vector< dealii::DataOutBase::Patch<patch_dim, patch_space_dim> > &
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_patches () const
+{
+  return patches;
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_finite_elements() const
+{
+  const unsigned int dhdim = DH::dimension;
+  const unsigned int dhspacedim = DH::space_dimension;
+  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dhdim,dhspacedim> > >
+    finite_elements(this->dof_data.size());
+  for (unsigned int i=0; i<this->dof_data.size(); ++i)
+    {
+      Assert (dof_data[i]->dof_handler != 0, ExcNoDoFHandlerSelected ());
+
+      // avoid creating too many finite elements and doing a lot of work on
+      // initializing FEValues downstream: if two DoFHandlers are the same
+      // (checked by pointer comparison), we can re-use the shared_ptr object
+      // for the second one. We cannot check for finite element equalities
+      // because we need different FEValues objects for different dof
+      // handlers.
+      bool duplicate = false;
+      for (unsigned int j=0; j<i; ++j)
+        if (dof_data[i]->dof_handler == dof_data[j]->dof_handler)
+          {
+            finite_elements[i] = finite_elements[j];
+            duplicate = true;
+          }
+      if (duplicate == false)
+        finite_elements[i].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
+                                 (this->dof_data[i]->dof_handler->get_fe()));
+    }
+  if (this->dof_data.empty())
+    {
+      finite_elements.resize(1);
+      finite_elements[0].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
+                               (FE_DGQ<dhdim,dhspacedim>(0)));
+    }
+  return finite_elements;
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+std::size_t
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::memory_consumption () const
+{
+  return (DataOutInterface<patch_dim,patch_space_dim>::memory_consumption () +
+          MemoryConsumption::memory_consumption (dofs) +
+          MemoryConsumption::memory_consumption (patches));
+}
+
+
+
+// explicit instantiations
+#include "data_out_dof_data.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/data_out_dof_data.inst.in b/deal.II/source/numerics/data_out_dof_data.inst.in
new file mode 100644 (file)
index 0000000..08ee608
--- /dev/null
@@ -0,0 +1,428 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2010 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
+{
+// codim=0
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
+// stuff needed for face data
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const VEC                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
+// things for DataOutRotation
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
+// codim 1
+
+  #if deal_II_dimension < 3
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const VEC                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
+  #endif
+
+
+
+// codim 2
+
+  #if deal_II_dimension == 3
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const VEC            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const VEC                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const VEC                 &,
+                      const DataPostprocessor<DH<1,3>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<1,3>::space_dimension> &);
+  #endif
+
+}
+
+
+
+for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
+{
+// codim=0
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet            &,
+                             const std::string   &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet                       &,
+                             const std::vector<std::string> &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
+// stuff needed for face data
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<IndexSet> (const IndexSet                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet            &,
+                             const std::string   &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet                       &,
+                             const std::vector<std::string> &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+// things for DataOutRotation
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet            &,
+                             const std::string   &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const DH<deal_II_dimension,deal_II_dimension> &,
+                             const IndexSet                       &,
+                             const std::vector<std::string> &,
+                             const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+// codim 1
+
+  #if deal_II_dimension < 3
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet            &,
+                       const std::string   &,
+                       const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet                       &,
+                     const std::vector<std::string> &,
+                     const DataVectorType,
+                     const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<IndexSet> (const IndexSet                 &,
+                      const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
+  #endif
+
+}
+
+
+
+for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
+{
+  template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension>;
+  template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension+1>;
+
+  #if deal_II_dimension < 3
+  template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension,deal_II_dimension+1>;
+  template class DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>;
+  #endif
+
+  #if deal_II_dimension >= 2
+  template class DataOut_DoFData<DH<deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>;
+  #endif
+
+  #if deal_II_dimension == 3
+     template class DataOut_DoFData<DH<1>,1,3>;
+     template class DataOut_DoFData<DH<1,3>,1,3>;
+  #endif
+
+}
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+{
+  namespace internal \{
+    namespace DataOut \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template struct ParallelDataBase<deal_II_dimension,deal_II_space_dimension>;
+#endif
+    \}
+  \}
+}
+
+
+for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+{
+  namespace internal \{
+    namespace DataOut \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template
+      void 
+      ParallelDataBase<deal_II_dimension,deal_II_space_dimension>::
+      reinit_all_fe_values<dealii::DH<deal_II_dimension,deal_II_space_dimension> >
+      (std::vector<std_cxx1x::shared_ptr<DataEntryBase<dealii::DH<deal_II_dimension,deal_II_space_dimension> > > > &dof_data,
+       const dealii::Triangulation<deal_II_dimension,deal_II_space_dimension>::cell_iterator &cell,
+       const unsigned int face);
+#endif
+    \}
+  \}
+}
index 46771ecc59e28fb605701816613fa113ff534736..83e89a9afae087c7ef56f21b782b4d2bd9a7ef81 100644 (file)
@@ -51,24 +51,14 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace
 {
-  inline
-  double sqr (const double x)
-  {
-    return x*x;
-  }
-
-
   template <typename CellIterator>
   inline
   void advance_by_n (CellIterator &cell,
                      const unsigned int n)
   {
-    // store a pointer to the end
-    // iterator, since we can't get at
-    // it any more once cell is already
-    // the end iterator (in that case
-    // dereferencing cell-> triggers an
-    // assertion)
+    // store a pointer to the end iterator, since we can't get at it any more
+    // once cell is already the end iterator (in that case dereferencing
+    // cell-> triggers an assertion)
     const CellIterator endc = cell->get_dof_handler().end();
     for (unsigned int t=0; ((t<n) && (cell!=endc)); ++t, ++cell)
       ;
@@ -81,60 +71,31 @@ namespace internal
   namespace
   {
     /**
-     * All small temporary data
-     * objects that are needed once
-     * per thread by the several
-     * functions of the error
-     * estimator are gathered in this
-     * struct. The reason for this
-     * structure is mainly that we
-     * have a number of functions
-     * that operate on cells or faces
-     * and need a number of small
-     * temporary data objects. Since
-     * these functions may run in
-     * parallel, we cannot make these
-     * objects member variables of
-     * the enclosing class. On the
-     * other hand, declaring them
-     * locally in each of these
-     * functions would require their
-     * reallocating every time we
-     * visit the next cell or face,
-     * which we found can take a
-     * significant amount of time if
-     * it happens often even in the
-     * single threaded case (10-20
-     * per cent in our measurements);
-     * however, most importantly,
-     * memory allocation requires
-     * synchronisation in
-     * multithreaded mode. While that
-     * is done by the C++ library and
-     * has not to be handcoded, it
-     * nevertheless seriously damages
-     * the ability to efficiently run
-     * the functions of this class in
-     * parallel, since they are quite
-     * often blocked by these
-     * synchronisation points,
-     * slowing everything down by a
-     * factor of two or three.
+     * All small temporary data objects that are needed once per thread by the
+     * several functions of the error estimator are gathered in this
+     * struct. The reason for this structure is mainly that we have a number
+     * of functions that operate on cells or faces and need a number of small
+     * temporary data objects. Since these functions may run in parallel, we
+     * cannot make these objects member variables of the enclosing class. On
+     * the other hand, declaring them locally in each of these functions would
+     * require their reallocating every time we visit the next cell or face,
+     * which we found can take a significant amount of time if it happens
+     * often even in the single threaded case (10-20 per cent in our
+     * measurements); however, most importantly, memory allocation requires
+     * synchronisation in multithreaded mode. While that is done by the C++
+     * library and has not to be handcoded, it nevertheless seriously damages
+     * the ability to efficiently run the functions of this class in parallel,
+     * since they are quite often blocked by these synchronisation points,
+     * slowing everything down by a factor of two or three.
      *
-     * Thus, every thread gets an
-     * instance of this class to work
-     * with and needs not allocate
-     * memory itself, or synchronise
-     * with other threads.
+     * Thus, every thread gets an instance of this class to work with and
+     * needs not allocate memory itself, or synchronise with other threads.
      *
-     * The sizes of the arrays are
-     * initialized with the maximal number of
-     * entries necessary for the hp
-     * case. Within the loop over individual
-     * cells, we then resize the arrays as
-     * necessary. Since for std::vector
-     * resizing to a smaller size doesn't
-     * imply memory allocation, this is fast.
+     * The sizes of the arrays are initialized with the maximal number of
+     * entries necessary for the hp case. Within the loop over individual
+     * cells, we then resize the arrays as necessary. Since for std::vector
+     * resizing to a smaller size doesn't imply memory allocation, this is
+     * fast.
      */
     template <class DH>
     struct ParallelData
@@ -148,14 +109,12 @@ namespace internal
       const dealii::hp::FECollection<dim,spacedim> finite_element;
 
       /**
-       * The quadrature formulas to be used for
-       * the faces.
+       * The quadrature formulas to be used for the faces.
        */
       const dealii::hp::QCollection<dim-1> face_quadratures;
 
       /**
-       * FEFaceValues objects to integrate over
-       * the faces of the current and
+       * FEFaceValues objects to integrate over the faces of the current and
        * potentially of neighbor cells.
        */
       dealii::hp::FEFaceValues<dim,spacedim>    fe_face_values_cell;
@@ -163,38 +122,22 @@ namespace internal
       dealii::hp::FESubfaceValues<dim,spacedim> fe_subface_values;
 
       /**
-       * A vector to store the jump
-       * of the normal vectors in
-       * the quadrature points for
-       * each of the solution
-       * vectors (i.e. a temporary
-       * value). This vector is not
-       * allocated inside the
-       * functions that use it, but
-       * rather globally, since
-       * memory allocation is slow,
-       * in particular in presence
-       * of multiple threads where
-       * synchronisation makes
-       * things even slower.
+       * A vector to store the jump of the normal vectors in the quadrature
+       * points for each of the solution vectors (i.e. a temporary
+       * value). This vector is not allocated inside the functions that use
+       * it, but rather globally, since memory allocation is slow, in
+       * particular in presence of multiple threads where synchronisation
+       * makes things even slower.
        */
       std::vector<std::vector<std::vector<double> > > phi;
 
       /**
-       * A vector for the gradients of
-       * the finite element function
-       * on one cell
+       * A vector for the gradients of the finite element function on one cell
        *
-       * Let psi be a short name
-       * for <tt>a grad u_h</tt>, where
-       * the third index be the
-       * component of the finite
-       * element, and the second
-       * index the number of the
-       * quadrature point. The
-       * first index denotes the
-       * index of the solution
-       * vector.
+       * Let psi be a short name for <tt>a grad u_h</tt>, where the third
+       * index be the component of the finite element, and the second index
+       * the number of the quadrature point. The first index denotes the index
+       * of the solution vector.
        */
       std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > psi;
 
@@ -204,43 +147,35 @@ namespace internal
       std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > neighbor_psi;
 
       /**
-       * The normal vectors of the finite
-       * element function on one face
+       * The normal vectors of the finite element function on one face
        */
       std::vector<Point<spacedim> > normal_vectors;
 
       /**
-       * Two arrays needed for the
-       * values of coefficients in
-       * the jumps, if they are
-       * given.
+       * Two arrays needed for the values of coefficients in the jumps, if
+       * they are given.
        */
       std::vector<double>                  coefficient_values1;
       std::vector<dealii::Vector<double> > coefficient_values;
 
       /**
-       * Array for the products of
-       * Jacobian determinants and
-       * weights of quadraturs
-       * points.
+       * Array for the products of Jacobian determinants and weights of
+       * quadraturs points.
        */
       std::vector<double>          JxW_values;
 
       /**
-       * The subdomain id we are to care
-       * for.
+       * The subdomain id we are to care for.
        */
       const types::subdomain_id subdomain_id;
       /**
-       * The material id we are to care
-       * for.
+       * The material id we are to care for.
        */
       const types::material_id material_id;
 
       /**
-       * Some more references to input data to
-       * the KellyErrorEstimator::estimate()
-       * function.
+       * Some more references to input data to the
+       * KellyErrorEstimator::estimate() function.
        */
       const typename FunctionMap<spacedim>::type *neumann_bc;
       const ComponentMask                component_mask;
@@ -262,10 +197,9 @@ namespace internal
                     const Function<spacedim>                   *coefficients);
 
       /**
-       * Resize the arrays so that they fit the
-       * number of quadrature points associated
-       * with the given finite element index
-       * into the hp collections.
+       * Resize the arrays so that they fit the number of quadrature points
+       * associated with the given finite element index into the hp
+       * collections.
        */
       void resize (const unsigned int active_fe_index);
     };
@@ -363,11 +297,9 @@ namespace internal
 
 
     /**
-     * Copy data from the
-     * local_face_integrals map of a single
-     * ParallelData object into a global such
-     * map. This is the copier stage of a
-     * WorkStream pipeline.
+     * Copy data from the local_face_integrals map of a single ParallelData
+     * object into a global such map. This is the copier stage of a WorkStream
+     * pipeline.
      */
     template <class DH>
     void
@@ -375,16 +307,14 @@ namespace internal
                           std::map<typename DH::face_iterator,std::vector<double> > &face_integrals)
     {
 
-      // now copy locally computed elements
-      // into the global map
+      // now copy locally computed elements into the global map
       for (typename std::map<typename DH::face_iterator,std::vector<double> >::const_iterator
            p=local_face_integrals.begin();
            p!=local_face_integrals.end();
            ++p)
         {
-          // double check that the
-          // element does not already
-          // exists in the global map
+          // double check that the element does not already exists in the
+          // global map
           Assert (face_integrals.find (p->first) == face_integrals.end(),
                   ExcInternalError());
 
@@ -400,105 +330,38 @@ namespace internal
 
 
     /**
-     * Actually do the computation on
-     * a face which has no hanging
-     * nodes (it is regular), i.e.
-     * either on the other side there
-     * is nirvana (face is at
-     * boundary), or the other side's
-     * refinement level is the same
-     * as that of this side, then
-     * handle the integration of
-     * these both cases together.
+     * Actually do the computation based on the evaluated gradients in
+     * ParallelData.
      */
-    template <typename InputVector, class DH>
-    void
-    integrate_over_regular_face (const std::vector<const InputVector *>   &solutions,
-                                 ParallelData<DH>                        &parallel_data,
-                                 std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
-                                 const typename DH::active_cell_iterator &cell,
-                                 const unsigned int                       face_no,
-                                 dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_cell,
-                                 dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_neighbor)
+    template <class DH>
+    std::vector<double>
+    integrate_over_face (ParallelData<DH>                        &parallel_data,
+                         const typename DH::face_iterator        &face,
+                         dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_cell)
     {
-      const unsigned int dim = DH::dimension;
-
-      const typename DH::face_iterator face = cell->face(face_no);
-      const unsigned int n_q_points         = parallel_data.face_quadratures[cell->active_fe_index()].size(),
+      const unsigned int n_q_points         = parallel_data.psi[0].size(),
                          n_components       = parallel_data.finite_element.n_components(),
-                         n_solution_vectors = solutions.size();
-
-
-      // initialize data of the restriction
-      // of this cell to the present face
-      fe_face_values_cell.reinit (cell, face_no,
-                                  cell->active_fe_index());
+                         n_solution_vectors = parallel_data.psi.size();
 
-      // get gradients of the finite element
-      // function on this cell
-      for (unsigned int n=0; n<n_solution_vectors; ++n)
-        fe_face_values_cell.get_present_fe_values()
-        .get_function_gradients (*solutions[n], parallel_data.psi[n]);
-
-      // now compute over the other side of
-      // the face
       if (face->at_boundary() == false)
-        // internal face; integrate jump
-        // of gradient across this face
         {
-          Assert (cell->neighbor(face_no).state() == IteratorState::valid,
-                  ExcInternalError());
-
-          const typename DH::active_cell_iterator neighbor = cell->neighbor(face_no);
-
-          // find which number the
-          // current face has relative to
-          // the neighboring cell
-          const unsigned int neighbor_neighbor
-            = cell->neighbor_of_neighbor (face_no);
-          Assert (neighbor_neighbor<GeometryInfo<dim>::faces_per_cell,
-                  ExcInternalError());
-
-          // get restriction of finite element
-          // function of @p{neighbor} to the
-          // common face. in the hp case, use the
-          // quadrature formula that matches the
-          // one we would use for the present
-          // cell
-          fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor,
-                                          cell->active_fe_index());
-
-          // get gradients on neighbor cell
+          // compute the jump in the gradients
           for (unsigned int n=0; n<n_solution_vectors; ++n)
-            {
-              fe_face_values_neighbor.get_present_fe_values()
-              .get_function_gradients (*solutions[n],
-                                       parallel_data.neighbor_psi[n]);
-
-              // compute the jump in the gradients
-              for (unsigned int component=0; component<n_components; ++component)
-                for (unsigned int p=0; p<n_q_points; ++p)
-                  parallel_data.psi[n][p][component] -= parallel_data.neighbor_psi[n][p][component];
-            }
+            for (unsigned int component=0; component<n_components; ++component)
+              for (unsigned int p=0; p<n_q_points; ++p)
+                parallel_data.psi[n][p][component] -= parallel_data.neighbor_psi[n][p][component];
         }
 
-
       // now psi contains the following:
       // - for an internal face, psi=[grad u]
-      // - for a neumann boundary face,
-      //   psi=grad u
-      // each component being the
-      // mentioned value at one of the
-      // quadrature points
-
-      // next we have to multiply this with
-      // the normal vector. Since we have
-      // taken the difference of gradients
-      // for internal faces, we may chose
-      // the normal vector of one cell,
-      // taking that of the neighbor
-      // would only change the sign. We take
-      // the outward normal.
+      // - for a neumann boundary face, psi=grad u
+      // each component being the mentioned value at one of the quadrature
+      // points
+
+      // next we have to multiply this with the normal vector. Since we have
+      // taken the difference of gradients for internal faces, we may chose
+      // the normal vector of one cell, taking that of the neighbor would only
+      // change the sign. We take the outward normal.
 
       parallel_data.normal_vectors =
         fe_face_values_cell.get_present_fe_values().get_normal_vectors();
@@ -510,14 +373,13 @@ namespace internal
               = (parallel_data.psi[n][point][component] *
                  parallel_data.normal_vectors[point]);
 
-      // if a coefficient was given: use that
-      // to scale the jump in the gradient
+      // if a coefficient was given: use that to scale the jump in the
+      // gradient
       if (parallel_data.coefficients != 0)
         {
           // scalar coefficient
           if (parallel_data.coefficients->n_components == 1)
             {
-
               parallel_data.coefficients
               ->value_list (fe_face_values_cell.get_present_fe_values()
                             .get_quadrature_points(),
@@ -545,18 +407,15 @@ namespace internal
 
 
       if (face->at_boundary() == true)
-        // neumann boundary face. compute
-        // difference between normal
-        // derivative and boundary function
+        // neumann boundary face. compute difference between normal derivative
+        // and boundary function
         {
           const types::boundary_id boundary_indicator = face->boundary_indicator();
 
           Assert (parallel_data.neumann_bc->find(boundary_indicator) !=
                   parallel_data.neumann_bc->end(),
                   ExcInternalError ());
-          // get the values of the boundary
-          // function at the quadrature
-          // points
+          // get the values of the boundary function at the quadrature points
           if (n_components == 1)
             {
               std::vector<double> g(n_q_points);
@@ -587,26 +446,94 @@ namespace internal
 
       // now phi contains the following:
       // - for an internal face, phi=[a du/dn]
-      // - for a neumann boundary face,
-      //   phi=a du/dn-g
-      // each component being the
-      // mentioned value at one of the
-      // quadrature points
+      // - for a neumann boundary face, phi=a du/dn-g
+      // each component being the mentioned value at one of the quadrature
+      // points
 
       parallel_data.JxW_values
         = fe_face_values_cell.get_present_fe_values().get_JxW_values();
 
-      // take the square of the phi[i]
-      // for integration, and sum up
+      // take the square of the phi[i] for integration, and sum up
       std::vector<double> face_integral (n_solution_vectors, 0);
       for (unsigned int n=0; n<n_solution_vectors; ++n)
         for (unsigned int component=0; component<n_components; ++component)
           if (parallel_data.component_mask[component] == true)
             for (unsigned int p=0; p<n_q_points; ++p)
-              face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
+              face_integral[n] += Utilities::fixed_power<2>(parallel_data.phi[n][p][component]) *
                                   parallel_data.JxW_values[p];
 
-      local_face_integrals[face] = face_integral;
+      return face_integral;
+    }
+
+
+
+    /**
+     * Actually do the computation on a face which has no hanging nodes (it is
+     * regular), i.e. either on the other side there is nirvana (face is at
+     * boundary), or the other side's refinement level is the same as that of
+     * this side, then handle the integration of these both cases together.
+     */
+    template <typename InputVector, class DH>
+    void
+    integrate_over_regular_face (const std::vector<const InputVector *>   &solutions,
+                                 ParallelData<DH>                        &parallel_data,
+                                 std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
+                                 const typename DH::active_cell_iterator &cell,
+                                 const unsigned int                       face_no,
+                                 dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_cell,
+                                 dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_neighbor)
+    {
+      const unsigned int dim = DH::dimension;
+
+      const typename DH::face_iterator face = cell->face(face_no);
+      const unsigned int n_solution_vectors = solutions.size();
+
+
+      // initialize data of the restriction
+      // of this cell to the present face
+      fe_face_values_cell.reinit (cell, face_no,
+                                  cell->active_fe_index());
+
+      // get gradients of the finite element
+      // function on this cell
+      for (unsigned int n=0; n<n_solution_vectors; ++n)
+        fe_face_values_cell.get_present_fe_values()
+        .get_function_gradients (*solutions[n], parallel_data.psi[n]);
+
+      // now compute over the other side of the face
+      if (face->at_boundary() == false)
+        // internal face; integrate jump of gradient across this face
+        {
+          Assert (cell->neighbor(face_no).state() == IteratorState::valid,
+                  ExcInternalError());
+
+          const typename DH::active_cell_iterator neighbor = cell->neighbor(face_no);
+
+          // find which number the current face has relative to the
+          // neighboring cell
+          const unsigned int neighbor_neighbor
+            = cell->neighbor_of_neighbor (face_no);
+          Assert (neighbor_neighbor<GeometryInfo<dim>::faces_per_cell,
+                  ExcInternalError());
+
+          // get restriction of finite element function of @p{neighbor} to the
+          // common face. in the hp case, use the quadrature formula that
+          // matches the one we would use for the present cell
+          fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor,
+                                          cell->active_fe_index());
+
+          // get gradients on neighbor cell
+          for (unsigned int n=0; n<n_solution_vectors; ++n)
+            {
+              fe_face_values_neighbor.get_present_fe_values()
+              .get_function_gradients (*solutions[n],
+                                       parallel_data.neighbor_psi[n]);
+            }
+        }
+
+      // now go to the generic function that does all the other things
+      local_face_integrals[face] =
+        integrate_over_face (parallel_data, face, fe_face_values_cell);
     }
 
 
@@ -624,8 +551,8 @@ namespace internal
      */
     template <typename InputVector, class DH>
     void
-    integrate_over_irregular_face (const std::vector<const InputVector *>      &solutions,
-                                   ParallelData<DH>                           &parallel_data,
+    integrate_over_irregular_face (const std::vector<const InputVector *>   &solutions,
+                                   ParallelData<DH>                         &parallel_data,
                                    std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
                                    const typename DH::active_cell_iterator    &cell,
                                    const unsigned int                          face_no,
@@ -635,28 +562,21 @@ namespace internal
       const unsigned int dim = DH::dimension;
 
       const typename DH::cell_iterator neighbor = cell->neighbor(face_no);
-      const unsigned int n_q_points         = parallel_data.face_quadratures[cell->active_fe_index()].size(),
-                         n_components       = parallel_data.finite_element.n_components(),
-                         n_solution_vectors = solutions.size();
+      const unsigned int n_solution_vectors = solutions.size();
       const typename DH::face_iterator
       face=cell->face(face_no);
 
       Assert (neighbor.state() == IteratorState::valid, ExcInternalError());
       Assert (face->has_children(), ExcInternalError());
-      // set up a vector of the gradients
-      // of the finite element function
-      // on this cell at the quadrature
-      // points
+
+      // set up a vector of the gradients of the finite element function on
+      // this cell at the quadrature points
       //
-      // let psi be a short name for
-      // [a grad u_h], where the second
-      // index be the component of the
-      // finite element, and the first
-      // index the number of the
-      // quadrature point
-
-      // store which number @p{cell} has
-      // in the list of neighbors of
+      // let psi be a short name for [a grad u_h], where the second index be
+      // the component of the finite element, and the first index the number
+      // of the quadrature point
+
+      // store which number @p{cell} has in the list of neighbors of
       // @p{neighbor}
       const unsigned int neighbor_neighbor
         = cell->neighbor_of_neighbor (face_no);
@@ -666,138 +586,38 @@ namespace internal
       // loop over all subfaces
       for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
         {
-          // get an iterator pointing to the
-          // cell behind the present subface
+          // get an iterator pointing to the cell behind the present subface
           const typename DH::active_cell_iterator neighbor_child
             = cell->neighbor_child_on_subface (face_no, subface_no);
           Assert (!neighbor_child->has_children(),
                   ExcInternalError());
 
-          // restrict the finite element
-          // on the present cell to the
-          // subface
+          // restrict the finite element on the present cell to the subface
           fe_subface_values.reinit (cell, face_no, subface_no,
                                     cell->active_fe_index());
 
-          // restrict the finite element
-          // on the neighbor cell to the
-          // common @p{subface}.
+          // restrict the finite element on the neighbor cell to the common
+          // @p{subface}.
           fe_face_values.reinit (neighbor_child, neighbor_neighbor,
                                  cell->active_fe_index());
 
-          // store the gradient of the
-          // solution in psi
+          // store the gradient of the solution in psi
           for (unsigned int n=0; n<n_solution_vectors; ++n)
             fe_subface_values.get_present_fe_values()
             .get_function_gradients (*solutions[n], parallel_data.psi[n]);
 
-          // store the gradient from the
-          // neighbor's side in
-          // @p{neighbor_psi}
+          // store the gradient from the neighbor's side in @p{neighbor_psi}
           for (unsigned int n=0; n<n_solution_vectors; ++n)
             fe_face_values.get_present_fe_values()
             .get_function_gradients (*solutions[n], parallel_data.neighbor_psi[n]);
 
-          // compute the jump in the gradients
-          for (unsigned int n=0; n<n_solution_vectors; ++n)
-            for (unsigned int component=0; component<n_components; ++component)
-              for (unsigned int p=0; p<n_q_points; ++p)
-                parallel_data.psi[n][p][component] -=
-                  parallel_data.neighbor_psi[n][p][component];
-
-          // note that unlike for the
-          // case of regular faces
-          // (treated in the other
-          // function of this class), we
-          // have not to take care of
-          // boundary faces here, since
-          // they always are regular.
-
-          // next we have to multiply this with
-          // the normal vector. Since we have
-          // taken the difference of gradients
-          // for internal faces, we may chose
-          // the normal vector of one cell,
-          // taking that of the neighbor
-          // would only change the sign. We take
-          // the outward normal.
-          //
-          // let phi be the name of the integrand
-
-          parallel_data.normal_vectors
-            = fe_face_values.get_present_fe_values().get_normal_vectors();
-
-
-          for (unsigned int n=0; n<n_solution_vectors; ++n)
-            for (unsigned int component=0; component<n_components; ++component)
-              for (unsigned int point=0; point<n_q_points; ++point)
-                parallel_data.phi[n][point][component] = (parallel_data.psi[n][point][component]*
-                                                          parallel_data.normal_vectors[point]);
-
-          // if a coefficient was given: use that
-          // to scale the jump in the gradient
-          if (parallel_data.coefficients != 0)
-            {
-              // scalar coefficient
-              if (parallel_data.coefficients->n_components == 1)
-                {
-                  parallel_data.coefficients
-                  ->value_list (fe_face_values.get_present_fe_values()
-                                .get_quadrature_points(),
-                                parallel_data.coefficient_values1);
-                  for (unsigned int n=0; n<n_solution_vectors; ++n)
-                    for (unsigned int component=0; component<n_components; ++component)
-                      for (unsigned int point=0; point<n_q_points; ++point)
-                        parallel_data.phi[n][point][component] *=
-                          parallel_data.coefficient_values1[point];
-                }
-              else
-                // vector-valued coefficient
-                {
-                  parallel_data.coefficients
-                  ->vector_value_list (fe_face_values.get_present_fe_values()
-                                       .get_quadrature_points(),
-                                       parallel_data.coefficient_values);
-                  for (unsigned int n=0; n<n_solution_vectors; ++n)
-                    for (unsigned int component=0; component<n_components; ++component)
-                      for (unsigned int point=0; point<n_q_points; ++point)
-                        parallel_data.phi[n][point][component] *=
-                          parallel_data.coefficient_values[point](component);
-                }
-            }
-
-          // get the weights for the
-          // integration. note that it
-          // does not matter whether we
-          // take the JxW values from the
-          // fe_face_values or the
-          // fe_subface_values, as the
-          // first is on the small
-          // neighbor cell, while the
-          // latter is on the refined
-          // face of the big cell here
-          parallel_data.JxW_values
-            = fe_face_values.get_present_fe_values().get_JxW_values();
-
-          // take the square of the phi[i]
-          // for integration, and sum up
-          std::vector<double> face_integral (n_solution_vectors, 0);
-          for (unsigned int n=0; n<n_solution_vectors; ++n)
-            for (unsigned int component=0; component<n_components; ++component)
-              if (parallel_data.component_mask[component] == true)
-                for (unsigned int p=0; p<n_q_points; ++p)
-                  face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
-                                      parallel_data.JxW_values[p];
-
-          local_face_integrals[neighbor_child->face(neighbor_neighbor)]
-            = face_integral;
+          // call generic evaluate function
+          local_face_integrals[neighbor_child->face(neighbor_neighbor)] =
+            integrate_over_face (parallel_data, face, fe_face_values);
         }
 
-
-      // finally loop over all subfaces to
-      // collect the contributions of the
-      // subfaces and store them with the
-      // mother face
+      // finally loop over all subfaces to collect the contributions of the
+      // subfaces and store them with the mother face
       std::vector<double> sum (n_solution_vectors, 0);
       for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
         {
@@ -816,29 +636,25 @@ namespace internal
 
 
     /**
-     * Computate the error on the faces of a
-     * single cell.
+     * Computate the error on the faces of a single cell.
      *
-     * This function is only needed
-     * in two or three dimensions.
-     * The error estimator in one
-     * dimension is implemented
-     * seperatly.
+     * This function is only needed in two or three dimensions.  The error
+     * estimator in one dimension is implemented separately.
      */
-    template <int dim, int spacedim, typename InputVector, class DH>
+    template <typename InputVector, class DH>
     void
     estimate_one_cell (const typename DH::active_cell_iterator &cell,
                        ParallelData<DH>                    &parallel_data,
                        std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
                        const std::vector<const InputVector *> &solutions)
     {
+      const unsigned int dim = DH::dimension;
       const unsigned int n_solution_vectors = solutions.size();
 
       const types::subdomain_id subdomain_id = parallel_data.subdomain_id;
       const unsigned int material_id  = parallel_data.material_id;
 
-      // empty our own copy of the local face
-      // integrals
+      // empty our own copy of the local face integrals
       local_face_integrals.clear();
 
       // loop over all faces of this cell
@@ -848,20 +664,11 @@ namespace internal
           const typename DH::face_iterator
           face=cell->face(face_no);
 
-          // make sure we do work
-          // only once: this face
-          // may either be regular
-          // or irregular. if it is
-          // regular and has a
-          // neighbor, then we
-          // visit the face twice,
-          // once from every
-          // side. let the one with
-          // the lower index do the
-          // work. if it is at the
-          // boundary, or if the
-          // face is irregular,
-          // then do the work below
+          // make sure we do work only once: this face may either be regular
+          // or irregular. if it is regular and has a neighbor, then we visit
+          // the face twice, once from every side. let the one with the lower
+          // index do the work. if it is at the boundary, or if the face is
+          // irregular, then do the work below
           if ((face->has_children() == false) &&
               !cell->at_boundary(face_no) &&
               (!cell->neighbor_is_coarser(face_no) &&
@@ -870,24 +677,17 @@ namespace internal
                  cell->neighbor(face_no)->level() < cell->level()))))
             continue;
 
-          // if the neighboring cell is less
-          // refined than the present one,
-          // then do nothing since we
-          // integrate over the subfaces when
-          // we visit the coarse cells.
+          // if the neighboring cell is less refined than the present one,
+          // then do nothing since we integrate over the subfaces when we
+          // visit the coarse cells.
           if (face->at_boundary() == false)
             if (cell->neighbor_is_coarser(face_no))
               continue;
 
-          // if this face is part of the
-          // boundary but not of the neumann
-          // boundary -> nothing to
-          // do. However, to make things
-          // easier when summing up the
-          // contributions of the faces of
-          // cells, we enter this face into
-          // the list of faces with
-          // contribution zero.
+          // if this face is part of the boundary but not of the neumann
+          // boundary -> nothing to do. However, to make things easier when
+          // summing up the contributions of the faces of cells, we enter this
+          // face into the list of faces with contribution zero.
           if (face->at_boundary()
               &&
               (parallel_data.neumann_bc->find(face->boundary_indicator()) ==
@@ -898,12 +698,9 @@ namespace internal
               continue;
             }
 
-          // finally: note that we only have
-          // to do something if either the
-          // present cell is on the subdomain
-          // we care for (and the same for
-          // material_id), or if one of the
-          // neighbors behind the face is on
+          // finally: note that we only have to do something if either the
+          // present cell is on the subdomain we care for (and the same for
+          // material_id), or if one of the neighbors behind the face is on
           // the subdomain we care for
           if ( ! ( ((subdomain_id == numbers::invalid_subdomain_id)
                     ||
@@ -913,11 +710,8 @@ namespace internal
                     ||
                     (cell->material_id() == material_id))) )
             {
-              // ok, cell is unwanted, but
-              // maybe its neighbor behind
-              // the face we presently work
-              // on? oh is there a face at
-              // all?
+              // ok, cell is unwanted, but maybe its neighbor behind the face
+              // we presently work on? oh is there a face at all?
               if (face->at_boundary())
                 continue;
 
@@ -950,32 +744,24 @@ namespace internal
                       }
                 }
 
-              // so if none of the neighbors
-              // cares for this subdomain or
-              // material either, then try
-              // next face
+              // so if none of the neighbors cares for this subdomain or
+              // material either, then try next face
               if (care_for_cell == false)
                 continue;
             }
 
-          // so now we know that we care for
-          // this face, let's do something
-          // about it. first re-size the
-          // arrays we may use to the correct
+          // so now we know that we care for this face, let's do something
+          // about it. first re-size the arrays we may use to the correct
           // size:
           parallel_data.resize (cell->active_fe_index());
 
 
           // then do the actual integration
           if (face->has_children() == false)
-            // if the face is a regular one,
-            // i.e.  either on the other side
-            // there is nirvana (face is at
-            // boundary), or the other side's
-            // refinement level is the same
-            // as that of this side, then
-            // handle the integration of
-            // these both cases together
+            // if the face is a regular one, i.e.  either on the other side
+            // there is nirvana (face is at boundary), or the other side's
+            // refinement level is the same as that of this side, then handle
+            // the integration of these both cases together
             integrate_over_regular_face (solutions,
                                          parallel_data,
                                          local_face_integrals,
@@ -984,10 +770,8 @@ namespace internal
                                          parallel_data.fe_face_values_neighbor);
 
           else
-            // otherwise we need to do some
-            // special computations which do
-            // not fit into the framework of
-            // the above function
+            // otherwise we need to do some special computations which do not
+            // fit into the framework of the above function
             integrate_over_irregular_face (solutions,
                                            parallel_data,
                                            local_face_integrals,
@@ -1003,418 +787,6 @@ namespace internal
 
 
 
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const Mapping<1,spacedim>      &mapping,
-          const DH   &dof_handler,
-          const Quadrature<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const InputVector       &solution,
-          Vector<float>           &error,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  // just pass on to the other function
-  const std::vector<const InputVector *> solutions (1, &solution);
-  std::vector<Vector<float>*>              errors (1, &error);
-  estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
-            component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const DH   &dof_handler,
-          const Quadrature<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const InputVector       &solution,
-          Vector<float>           &error,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
-           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const DH   &dof_handler,
-          const Quadrature<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const std::vector<const InputVector *> &solutions,
-          std::vector<Vector<float>*> &errors,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
-           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const Mapping<1,spacedim>      &mapping,
-          const DH   &dof_handler,
-          const hp::QCollection<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const InputVector       &solution,
-          Vector<float>           &error,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  // just pass on to the other function
-  const std::vector<const InputVector *> solutions (1, &solution);
-  std::vector<Vector<float>*>              errors (1, &error);
-  estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
-            component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const DH   &dof_handler,
-          const hp::QCollection<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const InputVector       &solution,
-          Vector<float>           &error,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
-           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void
-KellyErrorEstimator<1,spacedim>::
-estimate (const DH   &dof_handler,
-          const hp::QCollection<0> &quadrature,
-          const typename FunctionMap<spacedim>::type &neumann_bc,
-          const std::vector<const InputVector *> &solutions,
-          std::vector<Vector<float>*> &errors,
-          const ComponentMask &component_mask,
-          const Function<spacedim>     *coefficients,
-          const unsigned int       n_threads,
-          const types::subdomain_id subdomain_id,
-          const types::material_id       material_id)
-{
-  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
-           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
-}
-
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void KellyErrorEstimator<1,spacedim>::
-estimate (const Mapping<1,spacedim>                    &/*mapping*/,
-          const DH                            &/*dof_handler*/,
-          const hp::QCollection<0> &,
-          const typename FunctionMap<spacedim>::type          &/*neumann_bc*/,
-          const std::vector<const InputVector *> &/*solutions*/,
-          std::vector<Vector<float>*>            &/*errors*/,
-          const ComponentMask                &/*component_mask_*/,
-          const Function<spacedim>                   */*coefficient*/,
-          const unsigned int,
-          const types::subdomain_id          /*subdomain_id*/,
-          const types::material_id                   /*material_id*/)
-{
-  Assert (false, ExcInternalError());
-}
-
-
-
-template <int spacedim>
-template <typename InputVector, class DH>
-void KellyErrorEstimator<1,spacedim>::
-estimate (const Mapping<1,spacedim>                    &mapping,
-          const DH                 &dof_handler,
-          const Quadrature<0> &,
-          const typename FunctionMap<spacedim>::type          &neumann_bc,
-          const std::vector<const InputVector *> &solutions,
-          std::vector<Vector<float>*>              &errors,
-          const ComponentMask                  &component_mask,
-          const Function<spacedim>                   *coefficient,
-          const unsigned int,
-          const types::subdomain_id         subdomain_id_,
-          const types::material_id                  material_id)
-{
-#ifdef DEAL_II_WITH_P4EST
-  if (dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>*>
-      (&dof_handler.get_tria())
-      != 0)
-    Assert ((subdomain_id_ == numbers::invalid_subdomain_id)
-            ||
-            (subdomain_id_ ==
-             dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
-             (dof_handler.get_tria()).locally_owned_subdomain()),
-            ExcMessage ("For parallel distributed triangulations, the only "
-                        "valid subdomain_id that can be passed here is the "
-                        "one that corresponds to the locally owned subdomain id."));
-
-  const types::subdomain_id subdomain_id
-    = ((dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>*>
-        (&dof_handler.get_tria())
-        != 0)
-       ?
-       dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
-       (dof_handler.get_tria()).locally_owned_subdomain()
-       :
-       subdomain_id_);
-#else
-  const types::subdomain_id subdomain_id
-    = subdomain_id_;
-#endif
-
-  const unsigned int n_components       = dof_handler.get_fe().n_components();
-  const unsigned int n_solution_vectors = solutions.size();
-
-  // sanity checks
-  Assert (neumann_bc.find(numbers::internal_face_boundary_id) == neumann_bc.end(),
-          ExcInvalidBoundaryIndicator());
-
-  for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
-       i!=neumann_bc.end(); ++i)
-    Assert (i->second->n_components == n_components, ExcInvalidBoundaryFunction());
-
-  Assert (component_mask.represents_n_components(n_components),
-          ExcInvalidComponentMask());
-  Assert (component_mask.n_selected_components(n_components) > 0,
-          ExcInvalidComponentMask());
-
-  Assert ((coefficient == 0) ||
-          (coefficient->n_components == n_components) ||
-          (coefficient->n_components == 1),
-          ExcInvalidCoefficient());
-
-  Assert (solutions.size() > 0,
-          ExcNoSolutions());
-  Assert (solutions.size() == errors.size(),
-          ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
-  for (unsigned int n=0; n<solutions.size(); ++n)
-    Assert (solutions[n]->size() == dof_handler.n_dofs(),
-            ExcInvalidSolutionVector());
-
-  Assert ((coefficient == 0) ||
-          (coefficient->n_components == n_components) ||
-          (coefficient->n_components == 1),
-          ExcInvalidCoefficient());
-
-  for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
-       i!=neumann_bc.end(); ++i)
-    Assert (i->second->n_components == n_components,
-            ExcInvalidBoundaryFunction());
-
-  // reserve one slot for each cell and set
-  // it to zero
-  for (unsigned int n=0; n<n_solution_vectors; ++n)
-    (*errors[n]).reinit (dof_handler.get_tria().n_active_cells());
-
-  // fields to get the gradients on
-  // the present and the neighbor cell.
-  //
-  // for the neighbor gradient, we
-  // need several auxiliary fields,
-  // depending on the way we get it
-  // (see below)
-  std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
-  gradients_here (n_solution_vectors,
-                  std::vector<std::vector<Tensor<1,spacedim> > >(2, std::vector<Tensor<1,spacedim> >(n_components)));
-  std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
-  gradients_neighbor (gradients_here);
-  std::vector<Vector<double> >
-  grad_neighbor (n_solution_vectors, Vector<double>(n_components));
-
-  // reserve some space for
-  // coefficient values at one point.
-  // if there is no coefficient, then
-  // we fill it by unity once and for
-  // all and don't set it any more
-  Vector<double> coefficient_values (n_components);
-  if (coefficient == 0)
-    for (unsigned int c=0; c<n_components; ++c)
-      coefficient_values(c) = 1;
-
-  const QTrapez<1> quadrature;
-  const hp::QCollection<1> q_collection(quadrature);
-
-  const hp::FECollection<1,spacedim> fe (dof_handler.get_fe());
-
-  hp::MappingCollection<1,spacedim> mapping_collection;
-  mapping_collection.push_back (mapping);
-
-  hp::FEValues<1,spacedim> fe_values (mapping_collection, fe, q_collection,
-                                      update_gradients);
-
-  // loop over all cells and do something on
-  // the cells which we're told to work
-  // on. note that the error indicator is
-  // only a sum over the two contributions
-  // from the two vertices of each cell.
-  typename DH::active_cell_iterator cell = dof_handler.begin_active();
-  for (unsigned int cell_index=0; cell != dof_handler.end();
-       ++cell, ++cell_index)
-    if (((subdomain_id == numbers::invalid_subdomain_id)
-         ||
-         (cell->subdomain_id() == subdomain_id))
-        &&
-        ((material_id == numbers::invalid_material_id)
-         ||
-         (cell->material_id() == material_id)))
-      {
-        for (unsigned int n=0; n<n_solution_vectors; ++n)
-          (*errors[n])(cell_index) = 0;
-
-        // loop over the two points bounding
-        // this line. n==0 is left point,
-        // n==1 is right point
-        for (unsigned int n=0; n<2; ++n)
-          {
-            // find left or right active
-            // neighbor
-            typename DH::cell_iterator neighbor = cell->neighbor(n);
-            if (neighbor.state() == IteratorState::valid)
-              while (neighbor->has_children())
-                neighbor = neighbor->child(n==0 ? 1 : 0);
-
-            // now get the gradients on the
-            // both sides of the point
-            fe_values.reinit (cell);
-
-            for (unsigned int s=0; s<n_solution_vectors; ++s)
-              fe_values.get_present_fe_values()
-              .get_function_gradients (*solutions[s], gradients_here[s]);
-
-            if (neighbor.state() == IteratorState::valid)
-              {
-                fe_values.reinit (neighbor);
-
-                for (unsigned int s=0; s<n_solution_vectors; ++s)
-                  fe_values.get_present_fe_values()
-                  .get_function_gradients (*solutions[s],
-                                           gradients_neighbor[s]);
-
-                // extract the
-                // gradients of all the
-                // components. [0]
-                // means: x-derivative,
-                // which is the only
-                // one here
-                for (unsigned int s=0; s<n_solution_vectors; ++s)
-                  for (unsigned int c=0; c<n_components; ++c)
-                    grad_neighbor[s](c)
-                      = gradients_neighbor[s][n==0 ? 1 : 0][c][0];
-              }
-            else if (neumann_bc.find(n) != neumann_bc.end())
-              // if Neumann b.c., then fill
-              // the gradients field which
-              // will be used later on.
-              {
-                if (n_components==1)
-                  {
-                    const double
-                    v = neumann_bc.find(n)->second->value(cell->vertex(0));
-
-                    for (unsigned int s=0; s<n_solution_vectors; ++s)
-                      grad_neighbor[s](0) = v;
-                  }
-                else
-                  {
-                    Vector<double> v(n_components);
-                    neumann_bc.find(n)->second->vector_value(cell->vertex(0), v);
-
-                    for (unsigned int s=0; s<n_solution_vectors; ++s)
-                      grad_neighbor[s] = v;
-                  }
-              }
-            else
-              // fill with zeroes.
-              for (unsigned int s=0; s<n_solution_vectors; ++s)
-                grad_neighbor[s] = 0;
-
-            // if there is a
-            // coefficient, then
-            // evaluate it at the
-            // present position. if
-            // there is none, reuse the
-            // preset values.
-            if (coefficient != 0)
-              {
-                if (coefficient->n_components == 1)
-                  {
-                    const double c_value = coefficient->value (cell->vertex(n));
-                    for (unsigned int c=0; c<n_components; ++c)
-                      coefficient_values(c) = c_value;
-                  }
-                else
-                  coefficient->vector_value(cell->vertex(n),
-                                            coefficient_values);
-              }
-
-
-            for (unsigned int s=0; s<n_solution_vectors; ++s)
-              for (unsigned int component=0; component<n_components; ++component)
-                if (component_mask[component] == true)
-                  {
-                    // get gradient
-                    // here. [0] means
-                    // x-derivative
-                    // (there is no
-                    // other component
-                    // in 1d)
-                    const double grad_here = gradients_here[s][n][component][0];
-
-                    const double jump = ((grad_here - grad_neighbor[s](component)) *
-                                         coefficient_values(component));
-                    (*errors[s])(cell_index) += jump*jump * cell->diameter();
-                  }
-          }
-
-        for (unsigned int s=0; s<n_solution_vectors; ++s)
-          (*errors[s])(cell_index) = std::sqrt((*errors[s])(cell_index));
-      }
-}
-
-
-
-
-
-
 // the following function is still independent of dimension, but it
 // calls dimension dependent functions
 template <int dim, int spacedim>
@@ -1581,20 +953,14 @@ estimate (const Mapping<dim, spacedim>                  &mapping,
 
   const unsigned int n_solution_vectors = solutions.size();
 
-  // Map of integrals indexed by
-  // the corresponding face. In this map
-  // we store the integrated jump of the
-  // gradient for each face.
-  // At the end of the function, we again
-  // loop over the cells and collect the
-  // contributions of the different faces
-  // of the cell.
+  // Map of integrals indexed by the corresponding face. In this map we store
+  // the integrated jump of the gradient for each face.  At the end of the
+  // function, we again loop over the cells and collect the contributions of
+  // the different faces of the cell.
   std::map<typename DH::face_iterator,std::vector<double> > face_integrals;
 
-  // all the data needed in the error
-  // estimator by each of the threads
-  // is gathered in the following
-  // stuctures
+  // all the data needed in the error estimator by each of the threads is
+  // gathered in the following structures
   const hp::MappingCollection<dim,spacedim> mapping_collection(mapping);
   const internal::ParallelData<DH>
   parallel_data (dof_handler.get_fe(),
@@ -1612,18 +978,16 @@ estimate (const Mapping<dim, spacedim>                  &mapping,
   // now let's work on all those cells:
   WorkStream::run (dof_handler.begin_active(),
                    static_cast<typename DH::active_cell_iterator>(dof_handler.end()),
-                   std_cxx1x::bind (&internal::estimate_one_cell<dim,spacedim,InputVector,DH>,
+                   std_cxx1x::bind (&internal::estimate_one_cell<InputVector,DH>,
                                     std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::ref(solutions)),
                    std_cxx1x::bind (&internal::copy_local_to_global<DH>,
                                     std_cxx1x::_1, std_cxx1x::ref(face_integrals)),
                    parallel_data,
                    sample_local_face_integrals);
 
-  // finally add up the contributions of the
-  // faces for each cell
+  // finally add up the contributions of the faces for each cell
 
-  // reserve one slot for each cell and set
-  // it to zero
+  // reserve one slot for each cell and set it to zero
   for (unsigned int n=0; n<n_solution_vectors; ++n)
     {
       (*errors[n]).reinit (dof_handler.get_tria().n_active_cells());
@@ -1631,10 +995,8 @@ estimate (const Mapping<dim, spacedim>                  &mapping,
         (*errors[n])(i)=0;
     }
 
-  // now walk over all cells and collect
-  // information from the faces. only do
-  // something if this is a cell we care for
-  // based on the subdomain id
+  // now walk over all cells and collect information from the faces. only do
+  // something if this is a cell we care for based on the subdomain id
   unsigned int present_cell=0;
   for (typename DH::active_cell_iterator cell=dof_handler.begin_active();
        cell!=dof_handler.end();
@@ -1658,9 +1020,8 @@ estimate (const Mapping<dim, spacedim>                  &mapping,
 
             for (unsigned int n=0; n<n_solution_vectors; ++n)
               {
-                // make sure that we have
-                // written a meaningful value
-                // into this slot
+                // make sure that we have written a meaningful value into this
+                // slot
                 Assert (face_integrals[cell->face(face_no)][n] >= 0,
                         ExcInternalError());
 
index 34b06e672b499cdd56cd51d6af0c79fa844a1cc7..8ca601fbcfdb39c5babe7ba6d3b089f3df78bd39 100644 (file)
@@ -24,7 +24,7 @@ template class KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>;
 
 for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS; DH : DOFHANDLER_TEMPLATES )
 {
-#if deal_II_dimension <= deal_II_space_dimension
+#if deal_II_dimension != 1 && deal_II_dimension <= deal_II_space_dimension
 
 template
 void
diff --git a/deal.II/source/numerics/error_estimator_1d.cc b/deal.II/source/numerics/error_estimator_1d.cc
new file mode 100644 (file)
index 0000000..15b65d0
--- /dev/null
@@ -0,0 +1,439 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/base/thread_management.h>
+#include <deal.II/base/quadrature.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/work_stream.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/block_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
+#include <deal.II/lac/petsc_vector.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/base/geometry_info.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/hp/fe_values.h>
+#include <deal.II/fe/fe_update_flags.h>
+#include <deal.II/fe/mapping_q1.h>
+#include <deal.II/hp/q_collection.h>
+#include <deal.II/hp/mapping_collection.h>
+#include <deal.II/numerics/error_estimator.h>
+
+#include <deal.II/base/std_cxx1x/bind.h>
+
+#include <numeric>
+#include <algorithm>
+#include <cmath>
+#include <vector>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>      &mapping,
+          const DH   &dof_handler,
+          const Quadrature<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const InputVector       &solution,
+          Vector<float>           &error,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  // just pass on to the other function
+  const std::vector<const InputVector *> solutions (1, &solution);
+  std::vector<Vector<float>*>              errors (1, &error);
+  estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
+            component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const DH   &dof_handler,
+          const Quadrature<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const InputVector       &solution,
+          Vector<float>           &error,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
+           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const DH   &dof_handler,
+          const Quadrature<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const std::vector<const InputVector *> &solutions,
+          std::vector<Vector<float>*> &errors,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
+           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>      &mapping,
+          const DH   &dof_handler,
+          const hp::QCollection<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const InputVector       &solution,
+          Vector<float>           &error,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  // just pass on to the other function
+  const std::vector<const InputVector *> solutions (1, &solution);
+  std::vector<Vector<float>*>              errors (1, &error);
+  estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
+            component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const DH   &dof_handler,
+          const hp::QCollection<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const InputVector       &solution,
+          Vector<float>           &error,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
+           error, component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void
+KellyErrorEstimator<1,spacedim>::
+estimate (const DH   &dof_handler,
+          const hp::QCollection<0> &quadrature,
+          const typename FunctionMap<spacedim>::type &neumann_bc,
+          const std::vector<const InputVector *> &solutions,
+          std::vector<Vector<float>*> &errors,
+          const ComponentMask &component_mask,
+          const Function<spacedim>     *coefficients,
+          const unsigned int       n_threads,
+          const types::subdomain_id subdomain_id,
+          const types::material_id       material_id)
+{
+  estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
+           errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
+}
+
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>                    &/*mapping*/,
+          const DH                            &/*dof_handler*/,
+          const hp::QCollection<0> &,
+          const typename FunctionMap<spacedim>::type          &/*neumann_bc*/,
+          const std::vector<const InputVector *> &/*solutions*/,
+          std::vector<Vector<float>*>            &/*errors*/,
+          const ComponentMask                &/*component_mask_*/,
+          const Function<spacedim>                   */*coefficient*/,
+          const unsigned int,
+          const types::subdomain_id          /*subdomain_id*/,
+          const types::material_id                   /*material_id*/)
+{
+  Assert (false, ExcInternalError());
+}
+
+
+
+template <int spacedim>
+template <typename InputVector, class DH>
+void KellyErrorEstimator<1,spacedim>::
+estimate (const Mapping<1,spacedim>                    &mapping,
+          const DH                 &dof_handler,
+          const Quadrature<0> &,
+          const typename FunctionMap<spacedim>::type          &neumann_bc,
+          const std::vector<const InputVector *> &solutions,
+          std::vector<Vector<float>*>              &errors,
+          const ComponentMask                  &component_mask,
+          const Function<spacedim>                   *coefficient,
+          const unsigned int,
+          const types::subdomain_id         subdomain_id_,
+          const types::material_id                  material_id)
+{
+#ifdef DEAL_II_WITH_P4EST
+  if (dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>*>
+      (&dof_handler.get_tria())
+      != 0)
+    Assert ((subdomain_id_ == numbers::invalid_subdomain_id)
+            ||
+            (subdomain_id_ ==
+             dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
+             (dof_handler.get_tria()).locally_owned_subdomain()),
+            ExcMessage ("For parallel distributed triangulations, the only "
+                        "valid subdomain_id that can be passed here is the "
+                        "one that corresponds to the locally owned subdomain id."));
+
+  const types::subdomain_id subdomain_id
+    = ((dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>*>
+        (&dof_handler.get_tria())
+        != 0)
+       ?
+       dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
+       (dof_handler.get_tria()).locally_owned_subdomain()
+       :
+       subdomain_id_);
+#else
+  const types::subdomain_id subdomain_id
+    = subdomain_id_;
+#endif
+
+  const unsigned int n_components       = dof_handler.get_fe().n_components();
+  const unsigned int n_solution_vectors = solutions.size();
+
+  // sanity checks
+  Assert (neumann_bc.find(numbers::internal_face_boundary_id) == neumann_bc.end(),
+          ExcInvalidBoundaryIndicator());
+
+  for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
+       i!=neumann_bc.end(); ++i)
+    Assert (i->second->n_components == n_components, ExcInvalidBoundaryFunction());
+
+  Assert (component_mask.represents_n_components(n_components),
+          ExcInvalidComponentMask());
+  Assert (component_mask.n_selected_components(n_components) > 0,
+          ExcInvalidComponentMask());
+
+  Assert ((coefficient == 0) ||
+          (coefficient->n_components == n_components) ||
+          (coefficient->n_components == 1),
+          ExcInvalidCoefficient());
+
+  Assert (solutions.size() > 0,
+          ExcNoSolutions());
+  Assert (solutions.size() == errors.size(),
+          ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
+  for (unsigned int n=0; n<solutions.size(); ++n)
+    Assert (solutions[n]->size() == dof_handler.n_dofs(),
+            ExcInvalidSolutionVector());
+
+  Assert ((coefficient == 0) ||
+          (coefficient->n_components == n_components) ||
+          (coefficient->n_components == 1),
+          ExcInvalidCoefficient());
+
+  for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
+       i!=neumann_bc.end(); ++i)
+    Assert (i->second->n_components == n_components,
+            ExcInvalidBoundaryFunction());
+
+  // reserve one slot for each cell and set it to zero
+  for (unsigned int n=0; n<n_solution_vectors; ++n)
+    (*errors[n]).reinit (dof_handler.get_tria().n_active_cells());
+
+  // fields to get the gradients on the present and the neighbor cell.
+  //
+  // for the neighbor gradient, we need several auxiliary fields, depending on
+  // the way we get it (see below)
+  std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
+  gradients_here (n_solution_vectors,
+                  std::vector<std::vector<Tensor<1,spacedim> > >(2, std::vector<Tensor<1,spacedim> >(n_components)));
+  std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
+  gradients_neighbor (gradients_here);
+  std::vector<Vector<double> >
+  grad_neighbor (n_solution_vectors, Vector<double>(n_components));
+
+  // reserve some space for coefficient values at one point.  if there is no
+  // coefficient, then we fill it by unity once and for all and don't set it
+  // any more
+  Vector<double> coefficient_values (n_components);
+  if (coefficient == 0)
+    for (unsigned int c=0; c<n_components; ++c)
+      coefficient_values(c) = 1;
+
+  const QTrapez<1> quadrature;
+  const hp::QCollection<1> q_collection(quadrature);
+
+  const hp::FECollection<1,spacedim> fe (dof_handler.get_fe());
+
+  hp::MappingCollection<1,spacedim> mapping_collection;
+  mapping_collection.push_back (mapping);
+
+  hp::FEValues<1,spacedim> fe_values (mapping_collection, fe, q_collection,
+                                      update_gradients);
+
+  // loop over all cells and do something on the cells which we're told to
+  // work on. note that the error indicator is only a sum over the two
+  // contributions from the two vertices of each cell.
+  typename DH::active_cell_iterator cell = dof_handler.begin_active();
+  for (unsigned int cell_index=0; cell != dof_handler.end();
+       ++cell, ++cell_index)
+    if (((subdomain_id == numbers::invalid_subdomain_id)
+         ||
+         (cell->subdomain_id() == subdomain_id))
+        &&
+        ((material_id == numbers::invalid_material_id)
+         ||
+         (cell->material_id() == material_id)))
+      {
+        for (unsigned int n=0; n<n_solution_vectors; ++n)
+          (*errors[n])(cell_index) = 0;
+
+        // loop over the two points bounding this line. n==0 is left point,
+        // n==1 is right point
+        for (unsigned int n=0; n<2; ++n)
+          {
+            // find left or right active neighbor
+            typename DH::cell_iterator neighbor = cell->neighbor(n);
+            if (neighbor.state() == IteratorState::valid)
+              while (neighbor->has_children())
+                neighbor = neighbor->child(n==0 ? 1 : 0);
+
+            // now get the gradients on the both sides of the point
+            fe_values.reinit (cell);
+
+            for (unsigned int s=0; s<n_solution_vectors; ++s)
+              fe_values.get_present_fe_values()
+              .get_function_gradients (*solutions[s], gradients_here[s]);
+
+            if (neighbor.state() == IteratorState::valid)
+              {
+                fe_values.reinit (neighbor);
+
+                for (unsigned int s=0; s<n_solution_vectors; ++s)
+                  fe_values.get_present_fe_values()
+                  .get_function_gradients (*solutions[s],
+                                           gradients_neighbor[s]);
+
+                // extract the gradients of all the components. [0] means:
+                // x-derivative, which is the only one here
+                for (unsigned int s=0; s<n_solution_vectors; ++s)
+                  for (unsigned int c=0; c<n_components; ++c)
+                    grad_neighbor[s](c)
+                      = gradients_neighbor[s][n==0 ? 1 : 0][c][0];
+              }
+            else if (neumann_bc.find(n) != neumann_bc.end())
+              // if Neumann b.c., then fill the gradients field which will be
+              // used later on.
+              {
+                if (n_components==1)
+                  {
+                    const double
+                    v = neumann_bc.find(n)->second->value(cell->vertex(0));
+
+                    for (unsigned int s=0; s<n_solution_vectors; ++s)
+                      grad_neighbor[s](0) = v;
+                  }
+                else
+                  {
+                    Vector<double> v(n_components);
+                    neumann_bc.find(n)->second->vector_value(cell->vertex(0), v);
+
+                    for (unsigned int s=0; s<n_solution_vectors; ++s)
+                      grad_neighbor[s] = v;
+                  }
+              }
+            else
+              // fill with zeroes.
+              for (unsigned int s=0; s<n_solution_vectors; ++s)
+                grad_neighbor[s] = 0;
+
+            // if there is a coefficient, then evaluate it at the present
+            // position. if there is none, reuse the preset values.
+            if (coefficient != 0)
+              {
+                if (coefficient->n_components == 1)
+                  {
+                    const double c_value = coefficient->value (cell->vertex(n));
+                    for (unsigned int c=0; c<n_components; ++c)
+                      coefficient_values(c) = c_value;
+                  }
+                else
+                  coefficient->vector_value(cell->vertex(n),
+                                            coefficient_values);
+              }
+
+
+            for (unsigned int s=0; s<n_solution_vectors; ++s)
+              for (unsigned int component=0; component<n_components; ++component)
+                if (component_mask[component] == true)
+                  {
+                    // get gradient here. [0] means x-derivative (there is no
+                    // other component in 1d)
+                    const double grad_here = gradients_here[s][n][component][0];
+
+                    const double jump = ((grad_here - grad_neighbor[s](component)) *
+                                         coefficient_values(component));
+                    (*errors[s])(cell_index) += jump*jump * cell->diameter();
+                  }
+          }
+
+        for (unsigned int s=0; s<n_solution_vectors; ++s)
+          (*errors[s])(cell_index) = std::sqrt((*errors[s])(cell_index));
+      }
+}
+
+
+// explicit instantiations
+#include "error_estimator_1d.inst"
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/error_estimator_1d.inst.in b/deal.II/source/numerics/error_estimator_1d.inst.in
new file mode 100644 (file)
index 0000000..66b0c78
--- /dev/null
@@ -0,0 +1,143 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2010 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS; DH : DOFHANDLER_TEMPLATES )
+{
+#if deal_II_dimension == 1 && deal_II_dimension <= deal_II_space_dimension
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (const Mapping<deal_II_dimension, deal_II_space_dimension>      &,
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const Quadrature<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const VEC       &,
+          Vector<float>           &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const Quadrature<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const VEC       &,
+          Vector<float>           &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (const Mapping<deal_II_dimension, deal_II_space_dimension>      &,
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const Quadrature<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const std::vector<const VEC *>       &,
+          std::vector<Vector<float> *>         &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const Quadrature<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const std::vector<const VEC *>       &,
+          std::vector<Vector<float> *>         &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (const Mapping<deal_II_dimension, deal_II_space_dimension>      &,
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const hp::QCollection<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const VEC       &,
+          Vector<float>           &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const hp::QCollection<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const VEC       &,
+          Vector<float>           &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (const Mapping<deal_II_dimension, deal_II_space_dimension>      &,
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const hp::QCollection<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const std::vector<const VEC *>       &,
+          std::vector<Vector<float> *>         &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+template
+void
+KellyErrorEstimator<deal_II_dimension, deal_II_space_dimension>::
+estimate<VEC,DH<deal_II_dimension,deal_II_space_dimension> > (
+          const DH<deal_II_dimension,deal_II_space_dimension>   &,
+          const hp::QCollection<deal_II_dimension-1> &,
+          const FunctionMap<deal_II_space_dimension>::type &,
+          const std::vector<const VEC *>       &,
+          std::vector<Vector<float> *>         &,
+          const ComponentMask &,
+          const Function<deal_II_space_dimension>     *,
+          const unsigned int       ,
+          const unsigned int       ,
+          const types::material_id);
+
+#endif
+}
index 0a40a40830a5c6b4482322212085b9d7cbc3b577..beb4b0155d331a7aa41948feaca714d1a91d266c 100644 (file)
@@ -188,24 +188,13 @@ namespace internal
           {
             matrices(i,j).reinit (fe[i].dofs_per_cell, fe[j].dofs_per_cell);
 
-            // see if we can get the
-            // interpolation matrices
-            // for this combination
-            // of elements. if not,
-            // reset the matrix sizes
-            // to zero to indicate
-            // that this particular
-            // combination isn't
-            // supported. this isn't
-            // an outright error
-            // right away since we
-            // may never need to
-            // actually interpolate
-            // between these two
-            // elements on actual
-            // cells; we simply have
-            // to trigger an error if
-            // someone actually tries
+            // see if we can get the interpolation matrices for this
+            // combination of elements. if not, reset the matrix sizes to zero
+            // to indicate that this particular combination isn't
+            // supported. this isn't an outright error right away since we may
+            // never need to actually interpolate between these two elements
+            // on actual cells; we simply have to trigger an error if someone
+            // actually tries
             try
               {
                 fe[i].get_interpolation_matrix (fe[j], matrices(i,j));
@@ -574,12 +563,41 @@ interpolate (const std::vector<VECTOR> &all_in,
                           local_values.reinit (cell->has_children() ?
                                                cell->child(0)->get_fe().dofs_per_cell
                                                : cell->get_fe().dofs_per_cell, true);
-                          AssertDimension (local_values.size(),
-                                           interpolation_hp(new_fe_index,old_index).m());
+                         // do the interpolation. we get into trouble if the
+                         // interpolation_hp(new,old) matrix hasn't been computed.
+                         // this can happen if the respective elements don't support
+                         // the corresponding interpolation; if that's the case, then
+                         // the computation of the matrix simply sets the matrix
+                         // back to size zero. so if we get here and that is
+                         // the wrong size, then this may be because the elements
+                         // haven't implemented the correct function yet
+                         //
+                         // there is one wrinkle. we would like to only error out if
+                         // the size of the matrix is 0 times 0 but at least one
+                         // of the elements has more than one dof per cell. the
+                         // problem is that if you reinit a matrix to 4x0, it automatically
+                         // sets its size to 0x0. so we can only execute the following
+                         // test if *both* elements have dofs_per_cell>0, not if *at
+                         // least one* have.
+                         Assert (! ((interpolation_hp(new_fe_index,old_index).m() == 0)
+                                    &&
+                                    (interpolation_hp(new_fe_index,old_index).n() == 0)
+                                    &&
+                                    ((dof_handler->get_fe()[new_fe_index].dofs_per_cell > 0)
+                                     &&
+                                     (dof_handler->get_fe()[old_index].dofs_per_cell > 0))),
+                                 ExcMessage ("The interpolation between two different "
+                                             "elements you are trying to use here has "
+                                             "not been implemented for this pair of "
+                                             "elements!"));
+
                           // simple case where all children have the
                           // same FE index: just interpolate to their FE
                           // first and then use the standard routines
-                          interpolation_hp(new_fe_index,old_index).vmult (local_values, tmp);
+                         if (tmp.size() > 0)
+                           interpolation_hp(new_fe_index,old_index).vmult (local_values, tmp);
+                         else
+                           local_values = 0;
                         }
 
                       if (cell->has_children() == false)
@@ -596,9 +614,24 @@ interpolate (const std::vector<VECTOR> &all_in,
                                     AssertDimension (tmp.size(),
                                                      interpolation_hp(c_index,old_index).n());
                                     local_values.reinit(cell->child(child)->get_fe().dofs_per_cell, true);
-                                    AssertDimension (local_values.size(),
-                                                     interpolation_hp(c_index,old_index).m());
-                                    interpolation_hp(c_index,old_index).vmult (local_values, tmp);
+
+                                   // do the interpolation. same problem as above
+                                   Assert (! ((interpolation_hp(c_index,old_index).m() == 0)
+                                              &&
+                                              (interpolation_hp(c_index,old_index).n() == 0)
+                                              &&
+                                              ((dof_handler->get_fe()[c_index].dofs_per_cell > 0)
+                                               &&
+                                               (dof_handler->get_fe()[old_index].dofs_per_cell > 0))),
+                                           ExcMessage ("The interpolation between two different "
+                                                       "elements you are trying to use here has "
+                                                       "not been implemented for this pair of "
+                                                       "elements!"));
+
+                                   if (tmp.size() > 0)
+                                     interpolation_hp(c_index,old_index).vmult (local_values, tmp);
+                                    else
+                                      local_values = 0;
                                   }
                                 else
                                   local_values = tmp;
@@ -731,6 +764,8 @@ SolutionTransfer<dim, VECTOR, DH>::Pointerstruct::memory_consumption () const
 #define DIM_B 2
 #endif
 
+// This file compiles the first quarter of the instantiations from solution_transfer.cc
+// to reduce the compilation unit (and memory consumption)
 #include "solution_transfer.inst"
 
 DEAL_II_NAMESPACE_CLOSE
index fe64874d34b75e094cdfd9be0dd190490d63768d..05f27601063e6c19be3d69690756eb427330a5e2 100644 (file)
@@ -20,10 +20,13 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
 #if deal_II_dimension <= deal_II_space_dimension
 #if (deal_II_space_dimension == DIM_A) || (deal_II_space_dimension == DIM_B)
 
+#ifndef INSTANTIATE_HP_DH
     template class SolutionTransfer<deal_II_dimension, VEC, DoFHandler<deal_II_dimension, deal_II_space_dimension> >;
+#else
     template class SolutionTransfer<deal_II_dimension, VEC, hp::DoFHandler<deal_II_dimension, deal_II_space_dimension> >;
 #endif
 #endif
+#endif
 }
 
 
index 09c0cde1031424eafa4bb4ec56163d5e34e094db..8292d039e66f3c50fd3519ae4023a4e780840812 100644 (file)
 //
 // ---------------------------------------------------------------------
 
-// This file compiles the second half of the instantiations from solution_transfer.cc
-// to get the memory consumption below 1.5gb with gcc (if compiling with PETSc and Trilinos).
+// This file compiles the second quarter of the instantiations from solution_transfer.cc
+// to reduce the compilation unit (and memory consumption)
 
+//#define INSTANTIATE_HP_DH
 #define SOLUTION_TRANSFER_INSTANTIATE_PART_TWO
 
 #include "solution_transfer.cc"
diff --git a/deal.II/source/numerics/solution_transfer_inst3.cc b/deal.II/source/numerics/solution_transfer_inst3.cc
new file mode 100644 (file)
index 0000000..5ba125b
--- /dev/null
@@ -0,0 +1,23 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// This file compiles the third quarter of the instantiations from solution_transfer.cc
+// to reduce the compilation unit (and memory consumption)
+
+#define INSTANTIATE_HP_DH
+//#define SOLUTION_TRANSFER_INSTANTIATE_PART_TWO
+
+#include "solution_transfer.cc"
diff --git a/deal.II/source/numerics/solution_transfer_inst4.cc b/deal.II/source/numerics/solution_transfer_inst4.cc
new file mode 100644 (file)
index 0000000..f8c9518
--- /dev/null
@@ -0,0 +1,23 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// This file compiles the fourth quarter of the instantiations from solution_transfer.cc
+// to reduce the compilation unit (and memory consumption)
+
+#define INSTANTIATE_HP_DH
+#define SOLUTION_TRANSFER_INSTANTIATE_PART_TWO
+
+#include "solution_transfer.cc"
diff --git a/deal.II/source/numerics/vector_tools.inst.in b/deal.II/source/numerics/vector_tools.inst.in
deleted file mode 100644 (file)
index f7bbff3..0000000
+++ /dev/null
@@ -1,703 +0,0 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1998 - 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.
-//
-// ---------------------------------------------------------------------
-
-
-for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
-  {
-#if deal_II_dimension <= deal_II_space_dimension
-    namespace VectorTools \{
-
-      template
-        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
-        (const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
-         const VEC&,
-         const Function<deal_II_space_dimension>&,
-         Vector<float>&,
-         const Quadrature<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_space_dimension>*,
-         const double);
-
-      template
-        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension >
-        (const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
-         const VEC&,
-         const Function<deal_II_space_dimension>&,
-         Vector<double>&,
-         const Quadrature<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_space_dimension>*,
-         const double);
-
-      template
-        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
-        (const Mapping<deal_II_dimension, deal_II_space_dimension>&,
-         const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
-         const VEC&,
-         const Function<deal_II_space_dimension>&,
-         Vector<float>&,
-         const Quadrature<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_space_dimension>*,
-         const double);
-
-      template
-        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension >
-        (const Mapping<deal_II_dimension, deal_II_space_dimension>&,
-         const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
-         const VEC&,
-         const Function<deal_II_space_dimension>&,
-         Vector<double>&,
-         const Quadrature<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_space_dimension>*,
-         const double);
-
-
-
-      template
-        double compute_mean_value<deal_II_dimension>
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>&,
-         const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
-         const Quadrature<deal_II_dimension>&,
-         const VEC&,
-         const unsigned int);
-
-      template
-        double compute_mean_value<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
-         const Quadrature<deal_II_dimension>&,
-         const VEC&,
-         const unsigned int);
-
-      template
-        void interpolate
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>&,
-         const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
-         const Function<deal_II_space_dimension>&,
-         VEC&);
-
-      template
-        void interpolate
-        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
-         const Function<deal_II_space_dimension>&,
-         VEC&);
-
-      template
-        void project
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>      &,
-         const DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
-         const ConstraintMatrix                &,
-         const Quadrature<deal_II_dimension>   &,
-         const Function<deal_II_space_dimension>     &,
-         VEC                                   &,
-         const bool,
-         const Quadrature<deal_II_dimension-1> &,
-         const bool);
-
-      template
-        void project
-        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
-         const ConstraintMatrix                &,
-         const Quadrature<deal_II_dimension>   &,
-         const Function<deal_II_space_dimension>     &,
-         VEC                                   &,
-         const bool,
-         const Quadrature<deal_II_dimension-1> &,
-         const bool);
-
-      template
-        void project
-        (const hp::MappingCollection<deal_II_dimension,deal_II_space_dimension>      &,
-         const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
-         const ConstraintMatrix                &,
-         const hp::QCollection<deal_II_dimension>   &,
-         const Function<deal_II_space_dimension>     &,
-         VEC                                   &,
-         const bool,
-         const hp::QCollection<deal_II_dimension-1> &,
-         const bool);
-
-      template
-        void project
-        (const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
-         const ConstraintMatrix                &,
-         const hp::QCollection<deal_II_dimension>   &,
-         const Function<deal_II_space_dimension>     &,
-         VEC                                   &,
-         const bool,
-         const hp::QCollection<deal_II_dimension-1> &,
-         const bool);
-      \}
-#endif
-  }
-
-
-
-//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
-// where applicable and move to codimension cases above also when applicable
-for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
-  {
-#if deal_II_dimension == deal_II_space_dimension
-
-    namespace VectorTools \{
-
-  template
-    void point_value<deal_II_dimension> (
-      const hp::DoFHandler<deal_II_dimension>&,
-      const VEC&,
-      const Point<deal_II_dimension>&,
-      Vector<double>&);
-
-      template
-        void interpolate
-        (const Mapping<deal_II_dimension>&,
-         const hp::DoFHandler<deal_II_dimension>&,
-         const Function<deal_II_dimension>&,
-         VEC&);
-      template
-        void interpolate
-        (const hp::DoFHandler<deal_II_dimension>&,
-         const Function<deal_II_dimension>&,
-         VEC&);
-
-  template
-    double point_value<deal_II_dimension> (
-      const hp::DoFHandler<deal_II_dimension>&,
-      const VEC&,
-      const Point<deal_II_dimension>&);
-
-  template
-    void point_value<deal_II_dimension> (
-      const hp::MappingCollection<deal_II_dimension>&,
-      const hp::DoFHandler<deal_II_dimension>&,
-      const VEC&,
-      const Point<deal_II_dimension>&,
-      Vector<double>&);
-
-      template
-        void interpolate
-        (const DoFHandler<deal_II_dimension>&,
-         const DoFHandler<deal_II_dimension>&,
-         const FullMatrix<double>&,
-         const VEC&,
-         VEC&);
-
-  template
-    double point_value<deal_II_dimension> (
-      const hp::MappingCollection<deal_II_dimension>&,
-      const hp::DoFHandler<deal_II_dimension>&,
-      const VEC&,
-      const Point<deal_II_dimension>&);
-
-      template
-        void integrate_difference<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension>&,
-         const VEC&,
-         const Function<deal_II_dimension>&,
-         Vector<double>&,
-         const hp::QCollection<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_dimension>*,
-         const double);
-      template
-        void integrate_difference<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension>&,
-         const VEC&,
-         const Function<deal_II_dimension>&,
-         Vector<float>&,
-         const hp::QCollection<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_dimension>*,
-         const double);
-      template
-        void integrate_difference<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>&,
-         const hp::DoFHandler<deal_II_dimension>&,
-         const VEC&,
-         const Function<deal_II_dimension>&,
-         Vector<double>&,
-         const hp::QCollection<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_dimension>*,
-         const double);
-      template
-        void integrate_difference<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>&,
-         const hp::DoFHandler<deal_II_dimension>&,
-         const VEC&,
-         const Function<deal_II_dimension>&,
-         Vector<float>&,
-         const hp::QCollection<deal_II_dimension>&,
-         const NormType&,
-         const Function<deal_II_dimension>*,
-         const double);
-
-      template
-        void point_difference<deal_II_dimension> (
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Function<deal_II_dimension>&,
-          Vector<double>&,
-          const Point<deal_II_dimension>&);
-
-      template
-        void point_difference<deal_II_dimension> (
-          const Mapping<deal_II_dimension>&,
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Function<deal_II_dimension>&,
-          Vector<double>&,
-          const Point<deal_II_dimension>&);
-
-      template
-        void point_value<deal_II_dimension> (
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Point<deal_II_dimension>&,
-          Vector<double>&);
-
-      template
-        double point_value<deal_II_dimension> (
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Point<deal_II_dimension>&);
-
-      template
-        void point_value<deal_II_dimension> (
-          const Mapping<deal_II_dimension>&,
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Point<deal_II_dimension>&,
-          Vector<double>&);
-
-      template
-        double point_value<deal_II_dimension> (
-          const Mapping<deal_II_dimension>&,
-          const DoFHandler<deal_II_dimension>&,
-          const VEC&,
-          const Point<deal_II_dimension>&);
-
-      \}
-#endif
-  }
-
-
-for (VEC : SERIAL_VECTORS)
-{
-    namespace VectorTools \{
-      template
-        void subtract_mean_value(VEC &, const std::vector<bool> &);
-    \}
-}
-
-
-for (deal_II_dimension : DIMENSIONS)
-{
-    namespace VectorTools \{
-      template
-        void interpolate_boundary_values (
-          const MGDoFHandler<deal_II_dimension> &,
-          const types::boundary_id,
-          const Function<deal_II_dimension>   &,
-         ConstraintMatrix&,
-          const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values (
-          const MGDoFHandler<deal_II_dimension> &,
-          const types::boundary_id,
-          const Function<deal_II_dimension>   &,
-          std::map<types::global_dof_index,double>       &,
-          const ComponentMask    &);
-    \}
-}
-
-
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS; DH : DOFHANDLER_TEMPLATES)
-  {
-#if deal_II_dimension <= deal_II_space_dimension
-    namespace VectorTools \{
-      template
-        void interpolate_boundary_values
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
-         const DH<deal_II_dimension,deal_II_space_dimension> &,
-         const FunctionMap<deal_II_space_dimension>::type &,
-         std::map<types::global_dof_index,double>       &,
-         const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
-         const DH<deal_II_dimension,deal_II_space_dimension> &,
-         const types::boundary_id,
-         const Function<deal_II_space_dimension>   &,
-         std::map<types::global_dof_index,double>       &,
-         const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values (
-          const DH<deal_II_dimension,deal_II_space_dimension> &,
-          const types::boundary_id,
-          const Function<deal_II_space_dimension>   &,
-          std::map<types::global_dof_index,double>       &,
-          const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values
-        (const DH<deal_II_dimension,deal_II_space_dimension> &,
-         const FunctionMap<deal_II_space_dimension>::type &,
-         std::map<types::global_dof_index,double>       &,
-         const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values (
-          const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
-          const DH<deal_II_dimension,deal_II_space_dimension> &,
-          const FunctionMap<deal_II_space_dimension>::type   &,
-          ConstraintMatrix                    &,
-          const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
-         const DH<deal_II_dimension,deal_II_space_dimension> &,
-         const types::boundary_id,
-         const Function<deal_II_space_dimension>   &,
-         ConstraintMatrix                    &,
-         const ComponentMask             &);
-
-      template
-        void interpolate_boundary_values (
-          const DH<deal_II_dimension,deal_II_space_dimension> &,
-          const types::boundary_id,
-          const Function<deal_II_space_dimension>   &,
-          ConstraintMatrix                    &,
-          const ComponentMask    &);
-
-      template
-        void interpolate_boundary_values (
-          const DH<deal_II_dimension,deal_II_space_dimension> &,
-          const FunctionMap<deal_II_space_dimension>::type   &,
-          ConstraintMatrix                    &,
-          const ComponentMask    &);
-
-      \}
-#endif
-  }
-
-
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
-  {
-#if deal_II_dimension <= deal_II_space_dimension
-    namespace VectorTools \{
-      template
-        void create_right_hand_side<deal_II_dimension,deal_II_space_dimension>
-        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
-         const DoFHandler<deal_II_dimension,deal_II_space_dimension> &,
-         const Quadrature<deal_II_dimension> &,
-         const Function<deal_II_space_dimension>   &,
-         Vector<double>                      &);
-
-      template
-        void create_right_hand_side<deal_II_dimension,deal_II_space_dimension>
-        (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &,
-         const Quadrature<deal_II_dimension> &,
-         const Function<deal_II_space_dimension>   &,
-         Vector<double>  &);
-
-      \}
-#endif
-  }
-
-//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
-// where applicable and move to codimension cases above also when applicable
-for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
-  {
-    namespace VectorTools \{
-
-#if deal_II_dimension <= deal_II_space_dimension
-      template
-        void project_boundary_values<deal_II_dimension,deal_II_space_dimension>
-        (const hp::MappingCollection<deal_II_dimension,deal_II_space_dimension>  &,
-         const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>  &,
-         const FunctionMap<deal_II_space_dimension>::type &,
-         const hp::QCollection<deal_II_dimension-1>&,
-         std::map<types::global_dof_index,double>&, 
-         std::vector<unsigned int>);
-
-      template
-        void project_boundary_values<deal_II_dimension,deal_II_space_dimension>
-        (const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>  &,
-         const FunctionMap<deal_II_space_dimension>::type &,
-         const hp::QCollection<deal_II_dimension-1>&,
-         std::map<types::global_dof_index,double>&, 
-         std::vector<unsigned int>);
-#endif
-
-#if deal_II_dimension == deal_II_space_dimension
-      template
-        void create_right_hand_side<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>    &,
-         const hp::DoFHandler<deal_II_dimension> &,
-         const hp::QCollection<deal_II_dimension> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &);
-
-      template
-        void create_right_hand_side<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension> &,
-         const hp::QCollection<deal_II_dimension> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &);
-
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const Mapping<deal_II_dimension>    &,
-         const DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>    &,
-         const hp::DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const Mapping<deal_II_dimension>    &,
-         const DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>    &,
-         const hp::DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-      template
-        void create_point_source_vector<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension> &,
-         const Point<deal_II_dimension>      &,
-         const Point<deal_II_dimension>      &,
-         Vector<double>                      &);
-
-#if deal_II_dimension > 1
-      template
-        void
-        create_boundary_right_hand_side<deal_II_dimension>
-        (const Mapping<deal_II_dimension>    &,
-         const DoFHandler<deal_II_dimension> &,
-         const Quadrature<deal_II_dimension-1> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &,
-         const std::set<types::boundary_id> &);
-#endif
-
-      template
-        void
-        create_boundary_right_hand_side<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension> &,
-         const Quadrature<deal_II_dimension-1> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &,
-         const std::set<types::boundary_id> &);
-
-#if deal_II_dimension > 1
-      template
-        void
-        create_boundary_right_hand_side<deal_II_dimension>
-        (const hp::MappingCollection<deal_II_dimension>    &,
-         const hp::DoFHandler<deal_II_dimension> &,
-         const hp::QCollection<deal_II_dimension-1> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &,
-         const std::set<types::boundary_id> &);
-#endif
-
-      template
-        void
-        create_boundary_right_hand_side<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension> &,
-         const hp::QCollection<deal_II_dimension-1> &,
-         const Function<deal_II_dimension>   &,
-         Vector<double>                      &,
-         const std::set<types::boundary_id> &);
-
-
-
-
-
-      template
-        void project_boundary_values<deal_II_dimension>
-        (const Mapping<deal_II_dimension>     &,
-         const DoFHandler<deal_II_dimension>  &,
-         const FunctionMap<deal_II_dimension>::type &,
-         const Quadrature<deal_II_dimension-1>&,
-         std::map<types::global_dof_index,double>&, std::vector<unsigned int>);
-
-      template
-        void project_boundary_values<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension>  &,
-         const FunctionMap<deal_II_dimension>::type &,
-         const Quadrature<deal_II_dimension-1>&,
-         std::map<types::global_dof_index,double>&, 
-         std::vector<unsigned int>);
-
-      template
-        void project_boundary_values<deal_II_dimension>
-        (const Mapping<deal_II_dimension>     &,
-         const DoFHandler<deal_II_dimension>  &,
-         const FunctionMap<deal_II_dimension>::type &,
-         const Quadrature<deal_II_dimension-1>&,
-         ConstraintMatrix&, std::vector<unsigned int>);
-
-      template
-        void project_boundary_values<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension>  &,
-         const FunctionMap<deal_II_dimension>::type &,
-         const Quadrature<deal_II_dimension-1>&,
-         ConstraintMatrix&, 
-         std::vector<unsigned int>);
-
-
-
-#if deal_II_dimension != 1
-      template
-        void project_boundary_values_curl_conforming<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension>&,
-         const unsigned int,
-         const Function<deal_II_dimension>&,
-         const types::boundary_id,
-         ConstraintMatrix&,
-         const Mapping<deal_II_dimension>&);
-      template
-        void project_boundary_values_curl_conforming<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension>&,
-         const unsigned int,
-         const Function<deal_II_dimension>&,
-         const types::boundary_id,
-         ConstraintMatrix&,
-         const hp::MappingCollection<deal_II_dimension>&);
-      template
-        void project_boundary_values_div_conforming<deal_II_dimension>
-        (const DoFHandler<deal_II_dimension>&,
-         const unsigned int,
-         const Function<deal_II_dimension>&,
-         const types::boundary_id,
-         ConstraintMatrix&,
-         const Mapping<deal_II_dimension>&);
-      template
-        void project_boundary_values_div_conforming<deal_II_dimension>
-        (const hp::DoFHandler<deal_II_dimension>&,
-         const unsigned int,
-         const Function<deal_II_dimension>&,
-         const types::boundary_id,
-         ConstraintMatrix&,
-         const hp::MappingCollection<deal_II_dimension>&);
-      template
-        void
-        compute_no_normal_flux_constraints (const DoFHandler<deal_II_dimension> &dof_handler,
-                                            const unsigned int     first_vector_component,
-                                            const std::set<types::boundary_id> &boundary_ids,
-                                            ConstraintMatrix      &constraints,
-                                            const Mapping<deal_II_dimension>    &mapping);
-      template
-        void
-        compute_no_normal_flux_constraints (const hp::DoFHandler<deal_II_dimension> &dof_handler,
-                                            const unsigned int     first_vector_component,
-                                            const std::set<types::boundary_id> &boundary_ids,
-                                            ConstraintMatrix      &constraints,
-                                            const Mapping<deal_II_dimension>    &mapping);
-#endif
-#endif
-      \}
-  }
-
-
-
-for (deal_II_dimension : DIMENSIONS)
-{
-  namespace VectorTools \{
-
-  template
-    void interpolate_to_different_mesh
-    (const DoFHandler<deal_II_dimension> &,
-     const Vector<float>                 &,
-     const DoFHandler<deal_II_dimension> &,
-     Vector<float>                       &);
-
-  template
-    void interpolate_to_different_mesh
-    (const DoFHandler<deal_II_dimension> &,
-     const Vector<float>                 &,
-     const DoFHandler<deal_II_dimension> &,
-     const ConstraintMatrix              &,
-     Vector<float>                       &);
-
-  template
-    void interpolate_to_different_mesh
-    (const InterGridMap<DoFHandler<deal_II_dimension> > &,
-     const Vector<float>                                &,
-     const ConstraintMatrix                             &,
-     Vector<float>                                      &);
-
-  template
-    void interpolate_to_different_mesh
-    (const DoFHandler<deal_II_dimension> &,
-     const Vector<double>                &,
-     const DoFHandler<deal_II_dimension> &,
-     Vector<double>                      &);
-
-  template
-    void interpolate_to_different_mesh
-    (const DoFHandler<deal_II_dimension> &,
-     const Vector<double>                &,
-     const DoFHandler<deal_II_dimension> &,
-     const ConstraintMatrix              &,
-     Vector<double>                      &);
-
-  template
-    void interpolate_to_different_mesh
-    (const InterGridMap<DoFHandler<deal_II_dimension> > &,
-     const Vector<double>                               &,
-     const ConstraintMatrix                             &,
-     Vector<double>                                     &);
-
-  \}
-}
-
-
diff --git a/deal.II/source/numerics/vector_tools_boundary.cc b/deal.II/source/numerics/vector_tools_boundary.cc
new file mode 100644 (file)
index 0000000..6ecf213
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_boundary.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_boundary.inst.in b/deal.II/source/numerics/vector_tools_boundary.inst.in
new file mode 100644 (file)
index 0000000..813f195
--- /dev/null
@@ -0,0 +1,186 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (deal_II_dimension : DIMENSIONS)
+{
+    namespace VectorTools \{
+      template
+        void interpolate_boundary_values (
+          const MGDoFHandler<deal_II_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_dimension>   &,
+         ConstraintMatrix&,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const MGDoFHandler<deal_II_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_dimension>   &,
+          std::map<types::global_dof_index,double>       &,
+          const ComponentMask    &);
+    \}
+}
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS; DH : DOFHANDLER_TEMPLATES)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const FunctionMap<deal_II_space_dimension>::type &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const types::boundary_id,
+         const Function<deal_II_space_dimension>   &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_space_dimension>   &,
+          std::map<types::global_dof_index,double>       &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const FunctionMap<deal_II_space_dimension>::type &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const FunctionMap<deal_II_space_dimension>::type   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const types::boundary_id,
+         const Function<deal_II_space_dimension>   &,
+         ConstraintMatrix                    &,
+         const ComponentMask             &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_space_dimension>   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const FunctionMap<deal_II_space_dimension>::type   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+        \}
+#endif
+}
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
+  {
+    namespace VectorTools \{
+#if deal_II_dimension == deal_II_space_dimension
+
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const Mapping<deal_II_dimension>     &,
+         const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         std::map<types::global_dof_index,double>&, std::vector<unsigned int>);
+
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         std::map<types::global_dof_index,double>&, 
+         std::vector<unsigned int>);
+
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const Mapping<deal_II_dimension>     &,
+         const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         ConstraintMatrix&, std::vector<unsigned int>);
+
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         ConstraintMatrix&, 
+         std::vector<unsigned int>);
+
+
+
+#if deal_II_dimension != 1
+      template
+        void project_boundary_values_curl_conforming<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension>&,
+         const unsigned int,
+         const Function<deal_II_dimension>&,
+         const types::boundary_id,
+         ConstraintMatrix&,
+         const Mapping<deal_II_dimension>&);
+      template
+        void project_boundary_values_curl_conforming<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension>&,
+         const unsigned int,
+         const Function<deal_II_dimension>&,
+         const types::boundary_id,
+         ConstraintMatrix&,
+         const hp::MappingCollection<deal_II_dimension>&);
+      template
+        void project_boundary_values_div_conforming<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension>&,
+         const unsigned int,
+         const Function<deal_II_dimension>&,
+         const types::boundary_id,
+         ConstraintMatrix&,
+         const Mapping<deal_II_dimension>&);
+      template
+        void project_boundary_values_div_conforming<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension>&,
+         const unsigned int,
+         const Function<deal_II_dimension>&,
+         const types::boundary_id,
+         ConstraintMatrix&,
+         const hp::MappingCollection<deal_II_dimension>&);
+#endif
+#endif
+      \}
+  }
diff --git a/deal.II/source/numerics/vector_tools_constraints.cc b/deal.II/source/numerics/vector_tools_constraints.cc
new file mode 100644 (file)
index 0000000..1ec77ec
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_constraints.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_constraints.inst.in b/deal.II/source/numerics/vector_tools_constraints.inst.in
new file mode 100644 (file)
index 0000000..f3bfa2a
--- /dev/null
@@ -0,0 +1,58 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
+// where applicable and move to codimension cases above also when applicable
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+    namespace VectorTools \{
+
+#if deal_II_dimension == deal_II_space_dimension
+#if deal_II_dimension != 1
+      template
+        void
+        compute_no_normal_flux_constraints (const DoFHandler<deal_II_dimension> &dof_handler,
+                                            const unsigned int     first_vector_component,
+                                            const std::set<types::boundary_id> &boundary_ids,
+                                            ConstraintMatrix      &constraints,
+                                            const Mapping<deal_II_dimension>    &mapping);
+      template
+        void
+        compute_no_normal_flux_constraints (const hp::DoFHandler<deal_II_dimension> &dof_handler,
+                                            const unsigned int     first_vector_component,
+                                            const std::set<types::boundary_id> &boundary_ids,
+                                            ConstraintMatrix      &constraints,
+                                            const Mapping<deal_II_dimension>    &mapping);
+
+      template
+        void
+        compute_normal_flux_constraints (const DoFHandler<deal_II_dimension> &dof_handler,
+                                         const unsigned int     first_vector_component,
+                                         const std::set<types::boundary_id> &boundary_ids,
+                                         ConstraintMatrix      &constraints,
+                                         const Mapping<deal_II_dimension>    &mapping);
+      template
+        void
+        compute_normal_flux_constraints (const hp::DoFHandler<deal_II_dimension> &dof_handler,
+                                         const unsigned int     first_vector_component,
+                                         const std::set<types::boundary_id> &boundary_ids,
+                                         ConstraintMatrix      &constraints,
+                                         const Mapping<deal_II_dimension>    &mapping);
+#endif
+#endif
+      \}
+  }
diff --git a/deal.II/source/numerics/vector_tools_integrate_difference.cc b/deal.II/source/numerics/vector_tools_integrate_difference.cc
new file mode 100644 (file)
index 0000000..4e6e8e6
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_integrate_difference.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_integrate_difference.inst.in b/deal.II/source/numerics/vector_tools_integrate_difference.inst.in
new file mode 100644 (file)
index 0000000..4ad4fe0
--- /dev/null
@@ -0,0 +1,117 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
+        (const Mapping<deal_II_dimension, deal_II_space_dimension>&,
+         const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<float>&,
+         const Quadrature<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
+        (const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<float>&,
+         const Quadrature<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension >
+        (const Mapping<deal_II_dimension, deal_II_space_dimension>&,
+         const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<double>&,
+         const Quadrature<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension >
+        (const DoFHandler<deal_II_dimension, deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<double>&,
+         const Quadrature<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension>
+        (const hp::MappingCollection<deal_II_dimension,deal_II_space_dimension>&,
+         const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<double>&,
+         const hp::QCollection<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<double>, deal_II_space_dimension>
+        (const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<double>&,
+         const hp::QCollection<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
+        (const hp::MappingCollection<deal_II_dimension,deal_II_space_dimension>&,
+         const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<float>&,
+         const hp::QCollection<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      template
+        void integrate_difference<deal_II_dimension, VEC, Vector<float>, deal_II_space_dimension>
+        (const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const VEC&,
+         const Function<deal_II_space_dimension>&,
+         Vector<float>&,
+         const hp::QCollection<deal_II_dimension>&,
+         const NormType&,
+         const Function<deal_II_space_dimension>*,
+         const double);
+
+      \}
+#endif
+  }
diff --git a/deal.II/source/numerics/vector_tools_interpolate.cc b/deal.II/source/numerics/vector_tools_interpolate.cc
new file mode 100644 (file)
index 0000000..3d57d88
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_interpolate.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_interpolate.inst.in b/deal.II/source/numerics/vector_tools_interpolate.inst.in
new file mode 100644 (file)
index 0000000..5eba56a
--- /dev/null
@@ -0,0 +1,199 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+
+      template
+        void interpolate
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>&,
+         const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const Function<deal_II_space_dimension>&,
+         VEC&);
+
+      template
+        void interpolate
+        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const Function<deal_II_space_dimension>&,
+         VEC&);
+      \}
+#endif
+  }
+
+
+
+//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
+// where applicable and move to codimension cases above also when applicable
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension == deal_II_space_dimension
+
+    namespace VectorTools \{
+
+      template
+        void interpolate
+        (const Mapping<deal_II_dimension>&,
+         const hp::DoFHandler<deal_II_dimension>&,
+         const Function<deal_II_dimension>&,
+         VEC&);
+      template
+        void interpolate
+        (const hp::DoFHandler<deal_II_dimension>&,
+         const Function<deal_II_dimension>&,
+         VEC&);
+
+      template
+        void interpolate
+        (const DoFHandler<deal_II_dimension>&,
+         const DoFHandler<deal_II_dimension>&,
+         const FullMatrix<double>&,
+         const VEC&,
+         VEC&);
+      \}
+#endif
+  }
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS; DH : DOFHANDLER_TEMPLATES)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const FunctionMap<deal_II_space_dimension>::type &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const types::boundary_id,
+         const Function<deal_II_space_dimension>   &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_space_dimension>   &,
+          std::map<types::global_dof_index,double>       &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const FunctionMap<deal_II_space_dimension>::type &,
+         std::map<types::global_dof_index,double>       &,
+         const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const FunctionMap<deal_II_space_dimension>::type   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DH<deal_II_dimension,deal_II_space_dimension> &,
+         const types::boundary_id,
+         const Function<deal_II_space_dimension>   &,
+         ConstraintMatrix                    &,
+         const ComponentMask             &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const types::boundary_id,
+          const Function<deal_II_space_dimension>   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+
+      template
+        void interpolate_boundary_values (
+          const DH<deal_II_dimension,deal_II_space_dimension> &,
+          const FunctionMap<deal_II_space_dimension>::type   &,
+          ConstraintMatrix                    &,
+          const ComponentMask    &);
+
+      \}
+#endif
+  }
+
+
+
+for (deal_II_dimension : DIMENSIONS)
+{
+  namespace VectorTools \{
+
+  template
+    void interpolate_to_different_mesh
+    (const DoFHandler<deal_II_dimension> &,
+     const Vector<float>                 &,
+     const DoFHandler<deal_II_dimension> &,
+     Vector<float>                       &);
+
+  template
+    void interpolate_to_different_mesh
+    (const DoFHandler<deal_II_dimension> &,
+     const Vector<float>                 &,
+     const DoFHandler<deal_II_dimension> &,
+     const ConstraintMatrix              &,
+     Vector<float>                       &);
+
+  template
+    void interpolate_to_different_mesh
+    (const InterGridMap<DoFHandler<deal_II_dimension> > &,
+     const Vector<float>                                &,
+     const ConstraintMatrix                             &,
+     Vector<float>                                      &);
+
+  template
+    void interpolate_to_different_mesh
+    (const DoFHandler<deal_II_dimension> &,
+     const Vector<double>                &,
+     const DoFHandler<deal_II_dimension> &,
+     Vector<double>                      &);
+
+  template
+    void interpolate_to_different_mesh
+    (const DoFHandler<deal_II_dimension> &,
+     const Vector<double>                &,
+     const DoFHandler<deal_II_dimension> &,
+     const ConstraintMatrix              &,
+     Vector<double>                      &);
+
+  template
+    void interpolate_to_different_mesh
+    (const InterGridMap<DoFHandler<deal_II_dimension> > &,
+     const Vector<double>                               &,
+     const ConstraintMatrix                             &,
+     Vector<double>                                     &);
+
+  \}
+}
+
+
diff --git a/deal.II/source/numerics/vector_tools_mean_value.cc b/deal.II/source/numerics/vector_tools_mean_value.cc
new file mode 100644 (file)
index 0000000..a907916
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_mean_value.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_mean_value.inst.in b/deal.II/source/numerics/vector_tools_mean_value.inst.in
new file mode 100644 (file)
index 0000000..89e5be1
--- /dev/null
@@ -0,0 +1,50 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+
+      template
+        double compute_mean_value<deal_II_dimension>
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>&,
+         const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const Quadrature<deal_II_dimension>&,
+         const VEC&,
+         const unsigned int);
+
+      template
+        double compute_mean_value<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
+         const Quadrature<deal_II_dimension>&,
+         const VEC&,
+         const unsigned int);
+
+      \}
+#endif
+  }
+
+
+
+for (VEC : SERIAL_VECTORS)
+{
+    namespace VectorTools \{
+      template
+        void subtract_mean_value(VEC &, const std::vector<bool> &);
+    \}
+}
diff --git a/deal.II/source/numerics/vector_tools_point_value.cc b/deal.II/source/numerics/vector_tools_point_value.cc
new file mode 100644 (file)
index 0000000..e5a0c30
--- /dev/null
@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_point_value.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_point_value.inst.in b/deal.II/source/numerics/vector_tools_point_value.inst.in
new file mode 100644 (file)
index 0000000..8dd47f7
--- /dev/null
@@ -0,0 +1,165 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
+// where applicable and move to codimension cases above also when applicable
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension == deal_II_space_dimension
+
+    namespace VectorTools \{
+
+  template
+    void point_value<deal_II_dimension> (
+      const hp::DoFHandler<deal_II_dimension>&,
+      const VEC&,
+      const Point<deal_II_dimension>&,
+      Vector<double>&);
+
+  template
+    double point_value<deal_II_dimension> (
+      const hp::DoFHandler<deal_II_dimension>&,
+      const VEC&,
+      const Point<deal_II_dimension>&);
+
+  template
+    void point_value<deal_II_dimension> (
+      const hp::MappingCollection<deal_II_dimension>&,
+      const hp::DoFHandler<deal_II_dimension>&,
+      const VEC&,
+      const Point<deal_II_dimension>&,
+      Vector<double>&);
+
+  template
+    double point_value<deal_II_dimension> (
+      const hp::MappingCollection<deal_II_dimension>&,
+      const hp::DoFHandler<deal_II_dimension>&,
+      const VEC&,
+      const Point<deal_II_dimension>&);
+
+      template
+        void point_difference<deal_II_dimension> (
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Function<deal_II_dimension>&,
+          Vector<double>&,
+          const Point<deal_II_dimension>&);
+
+      template
+        void point_difference<deal_II_dimension> (
+          const Mapping<deal_II_dimension>&,
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Function<deal_II_dimension>&,
+          Vector<double>&,
+          const Point<deal_II_dimension>&);
+
+      template
+        void point_value<deal_II_dimension> (
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Point<deal_II_dimension>&,
+          Vector<double>&);
+
+      template
+        double point_value<deal_II_dimension> (
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Point<deal_II_dimension>&);
+
+      template
+        void point_value<deal_II_dimension> (
+          const Mapping<deal_II_dimension>&,
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Point<deal_II_dimension>&,
+          Vector<double>&);
+
+      template
+        double point_value<deal_II_dimension> (
+          const Mapping<deal_II_dimension>&,
+          const DoFHandler<deal_II_dimension>&,
+          const VEC&,
+          const Point<deal_II_dimension>&);
+
+      \}
+#endif
+  }
+
+
+
+//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
+// where applicable and move to codimension cases above also when applicable
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+    namespace VectorTools \{
+
+#if deal_II_dimension == deal_II_space_dimension
+
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const Mapping<deal_II_dimension>    &,
+         const DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const hp::MappingCollection<deal_II_dimension>    &,
+         const hp::DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const Mapping<deal_II_dimension>    &,
+         const DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const hp::MappingCollection<deal_II_dimension>    &,
+         const hp::DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+      template
+        void create_point_source_vector<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension> &,
+         const Point<deal_II_dimension>      &,
+         const Point<deal_II_dimension>      &,
+         Vector<double>                      &);
+#endif
+      \}
+  }
similarity index 95%
rename from deal.II/source/numerics/vector_tools.cc
rename to deal.II/source/numerics/vector_tools_project.cc
index fe9539c1d0f736331ccd26797e61dc0514f19426..cd5ba6fb7a19550c4a2ea1f355dd2078b94b3dce 100644 (file)
@@ -20,6 +20,6 @@
 DEAL_II_NAMESPACE_OPEN
 
 // ---------------------------- explicit instantiations --------------------
-#include "vector_tools.inst"
+#include "vector_tools_project.inst"
 
 DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_project.inst.in b/deal.II/source/numerics/vector_tools_project.inst.in
new file mode 100644 (file)
index 0000000..3dc5d6b
--- /dev/null
@@ -0,0 +1,70 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (VEC : SERIAL_VECTORS ; deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+
+      template
+        void project
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>      &,
+         const DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
+         const ConstraintMatrix                &,
+         const Quadrature<deal_II_dimension>   &,
+         const Function<deal_II_space_dimension>     &,
+         VEC                                   &,
+         const bool,
+         const Quadrature<deal_II_dimension-1> &,
+         const bool);
+
+      template
+        void project
+        (const DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
+         const ConstraintMatrix                &,
+         const Quadrature<deal_II_dimension>   &,
+         const Function<deal_II_space_dimension>     &,
+         VEC                                   &,
+         const bool,
+         const Quadrature<deal_II_dimension-1> &,
+         const bool);
+
+      template
+        void project
+        (const hp::MappingCollection<deal_II_dimension,deal_II_space_dimension>      &,
+         const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
+         const ConstraintMatrix                &,
+         const hp::QCollection<deal_II_dimension>   &,
+         const Function<deal_II_space_dimension>     &,
+         VEC                                   &,
+         const bool,
+         const hp::QCollection<deal_II_dimension-1> &,
+         const bool);
+
+      template
+        void project
+        (const hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>   &,
+         const ConstraintMatrix                &,
+         const hp::QCollection<deal_II_dimension>   &,
+         const Function<deal_II_space_dimension>     &,
+         VEC                                   &,
+         const bool,
+         const hp::QCollection<deal_II_dimension-1> &,
+         const bool);
+      \}
+#endif
+  }
diff --git a/deal.II/source/numerics/vector_tools_rhs.cc b/deal.II/source/numerics/vector_tools_rhs.cc
new file mode 100644 (file)
index 0000000..cb12d60
--- /dev/null
@@ -0,0 +1,86 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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 <deal.II/numerics/vector_tools.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+namespace VectorTools
+{
+
+// separate implementation for 1D because otherwise we get linker errors since
+// (hp::)FEFaceValues<1> is not compiled
+  template <>
+  void
+  create_boundary_right_hand_side (const Mapping<1,1> &,
+                                   const DoFHandler<1,1> &,
+                                   const Quadrature<0> &,
+                                   const Function<1> &,
+                                   Vector<double> &,
+                                   const std::set<types::boundary_id> &)
+  {
+    Assert (false, ExcImpossibleInDim(1));
+  }
+
+
+
+  template <>
+  void
+  create_boundary_right_hand_side (const Mapping<1,2> &,
+                                   const DoFHandler<1,2> &,
+                                   const Quadrature<0> &,
+                                   const Function<2> &,
+                                   Vector<double> &,
+                                   const std::set<types::boundary_id> &)
+  {
+    Assert (false, ExcImpossibleInDim(1));
+  }
+
+
+
+  template <>
+  void
+  create_boundary_right_hand_side (const hp::MappingCollection<1,1> &,
+                                   const hp::DoFHandler<1,1> &,
+                                   const hp::QCollection<0> &,
+                                   const Function<1> &,
+                                   Vector<double> &,
+                                   const std::set<types::boundary_id> &)
+  {
+    Assert (false, ExcImpossibleInDim(1));
+  }
+
+
+
+  template <>
+  void
+  create_boundary_right_hand_side (const hp::MappingCollection<1,2> &,
+                                   const hp::DoFHandler<1,2> &,
+                                   const hp::QCollection<0> &,
+                                   const Function<2> &,
+                                   Vector<double> &,
+                                   const std::set<types::boundary_id> &)
+  {
+    Assert (false, ExcImpossibleInDim(1));
+  }
+}
+
+// ---------------------------- explicit instantiations --------------------
+#include "vector_tools_rhs.inst"
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/deal.II/source/numerics/vector_tools_rhs.inst.in b/deal.II/source/numerics/vector_tools_rhs.inst.in
new file mode 100644 (file)
index 0000000..aed42a7
--- /dev/null
@@ -0,0 +1,108 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 1998 - 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.
+//
+// ---------------------------------------------------------------------
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+#if deal_II_dimension <= deal_II_space_dimension
+    namespace VectorTools \{
+      template
+        void create_right_hand_side<deal_II_dimension,deal_II_space_dimension>
+        (const Mapping<deal_II_dimension,deal_II_space_dimension>    &,
+         const DoFHandler<deal_II_dimension,deal_II_space_dimension> &,
+         const Quadrature<deal_II_dimension> &,
+         const Function<deal_II_space_dimension>   &,
+         Vector<double>                      &);
+
+      template
+        void create_right_hand_side<deal_II_dimension,deal_II_space_dimension>
+        (const DoFHandler<deal_II_dimension,deal_II_space_dimension> &,
+         const Quadrature<deal_II_dimension> &,
+         const Function<deal_II_space_dimension>   &,
+         Vector<double>  &);
+
+      \}
+#endif
+  }
+
+//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
+// where applicable and move to codimension cases above also when applicable
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
+  {
+    namespace VectorTools \{
+
+#if deal_II_dimension == deal_II_space_dimension
+      template
+        void create_right_hand_side<deal_II_dimension>
+        (const hp::MappingCollection<deal_II_dimension>    &,
+         const hp::DoFHandler<deal_II_dimension> &,
+         const hp::QCollection<deal_II_dimension> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &);
+
+      template
+        void create_right_hand_side<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension> &,
+         const hp::QCollection<deal_II_dimension> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &);
+
+#if deal_II_dimension > 1
+      template
+        void
+        create_boundary_right_hand_side<deal_II_dimension>
+        (const Mapping<deal_II_dimension>    &,
+         const DoFHandler<deal_II_dimension> &,
+         const Quadrature<deal_II_dimension-1> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &,
+         const std::set<types::boundary_id> &);
+#endif
+
+      template
+        void
+        create_boundary_right_hand_side<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension> &,
+         const Quadrature<deal_II_dimension-1> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &,
+         const std::set<types::boundary_id> &);
+
+#if deal_II_dimension > 1
+      template
+        void
+        create_boundary_right_hand_side<deal_II_dimension>
+        (const hp::MappingCollection<deal_II_dimension>    &,
+         const hp::DoFHandler<deal_II_dimension> &,
+         const hp::QCollection<deal_II_dimension-1> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &,
+         const std::set<types::boundary_id> &);
+#endif
+
+      template
+        void
+        create_boundary_right_hand_side<deal_II_dimension>
+        (const hp::DoFHandler<deal_II_dimension> &,
+         const hp::QCollection<deal_II_dimension-1> &,
+         const Function<deal_II_dimension>   &,
+         Vector<double>                      &,
+         const std::set<types::boundary_id> &);
+
+
+#endif
+      \}
+  }

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.