INCLUDE(setup_custom_targets)
INCLUDE(setup_finalize)
INCLUDE(setup_write_config)
+#INCLUDE(setup_sanity_checks)
########################################################################
PATTERN ".svn" EXCLUDE
)
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
- "${BOOST_FOLDER}/include\n"
- )
-
ADD_SUBDIRECTORY(${BOOST_FOLDER}/libs/serialization/src)
IF(DEAL_II_WITH_ZLIB)
PATTERN ".svn" EXCLUDE
)
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
- "${TBB_FOLDER}/include\n"
- )
-
ADD_SUBDIRECTORY(${TBB_FOLDER}/src)
ENDIF()
##
## ---------------------------------------------------------------------
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
SET(src_boost_iostreams
file_descriptor.cpp
gzip.cpp
##
## ---------------------------------------------------------------------
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
SET(src_boost_serialization
basic_archive.cpp
basic_iarchive.cpp
##
## ---------------------------------------------------------------------
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
IF(DEAL_II_USE_MT_POSIX)
SET(src_boost_thread
pthread/once.cpp
SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
INCLUDE_DIRECTORIES(
+ ${THREADS_BUNDLED_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/rml/include
)
##
## ---------------------------------------------------------------------
+INCLUDE_DIRECTORIES(${UMFPACK_BUNDLED_INCLUDE_DIRS})
+
SET(src_amd
amd_1.cc
amd_2.cc
# (... where everything is explained contrary to this... mess)
#
+INCLUDE_DIRECTORIES(${UMFPACK_BUNDLED_INCLUDE_DIRS})
+
#
# *Shush!*
+# (Remove locally in this subdirectory)
#
STRIP_FLAG(DEAL_II_CXX_FLAGS "-pedantic")
STRIP_FLAG(DEAL_II_CXX_FLAGS "-Wall")
#
# Do we have the Bessel function jn?
#
-# Switch the library preference back to prefer dynamic libraries if
-# DEAL_II_PREFER_STATIC_LIBS=TRUE but DEAL_II_STATIC_EXECUTABLE=FALSE. In
-# this case system libraries should be linked dynamically.
-#
-SWITCH_LIBRARY_PREFERENCE()
-FIND_LIBRARY(m_LIBRARY NAMES m)
-SWITCH_LIBRARY_PREFERENCE()
+FIND_SYSTEM_LIBRARY(m_LIBRARY NAMES m)
MARK_AS_ADVANCED(m_LIBRARY)
IF(NOT m_LIBRARY MATCHES "-NOTFOUND")
CHECK_CXX_SYMBOL_EXISTS("jn" "math.h" HAVE_JN)
RESET_CMAKE_REQUIRED()
IF(HAVE_JN)
- LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${m_LIBRARY})
+ LIST(APPEND DEAL_II_LIBRARIES ${m_LIBRARY})
ENDIF()
ENDIF()
MESSAGE(STATUS "Setting up project configuration")
-#
-# Read in auxiliary include directories for the build directory
-# configuration:
-#
-FILE(STRINGS
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
- deal_ii_source_includes
- )
-
#
# Configure the template-arguments file
#
ENDIF()
LIST(APPEND CONFIG_LIBRARIES_${_build}
- ${DEAL_II_EXTERNAL_LIBRARIES_${_build}}
- ${DEAL_II_EXTERNAL_LIBRARIES}
+ ${DEAL_II_LIBRARIES_${_build}}
+ ${DEAL_II_LIBRARIES}
)
LIST(APPEND CONFIG_LIBRARIES
${_keyword}
\${DEAL_II_PATH}/include/deal.II
${CMAKE_SOURCE_DIR}/include/
${CMAKE_SOURCE_DIR}/include/deal.II
- ${deal_ii_source_includes}
+ ${DEAL_II_BUNDLED_INCLUDE_DIRS}
${DEAL_II_USER_INCLUDE_DIRS}
)
CONFIGURE_FILE(
SET(_libs)
FOREACH(_lib
- ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
- ${DEAL_II_EXTERNAL_LIBRARIES}
+ ${DEAL_II_LIBRARIES_${build}}
+ ${DEAL_II_LIBRARIES}
)
IF(_lib MATCHES "^\\s*\\/" AND NOT _lib MATCHES "\\.framework$")
LIST(APPEND _libs "${_lib}")
SET(_paths)
FOREACH(_lib
$(D)/${DEAL_II_LIBRARY_RELDIR}/${CONFIG_LIBRARY_${build}}
- ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
- ${DEAL_II_EXTERNAL_LIBRARIES}
+ ${DEAL_II_LIBRARIES_${build}}
+ ${DEAL_II_LIBRARIES}
)
#
$(D)/install/deal.II
${CMAKE_SOURCE_DIR}/include/
${CMAKE_SOURCE_DIR}/include/deal.II
- ${deal_ii_source_includes}
+ ${DEAL_II_BUNDLED_INCLUDE_DIRS}
${DEAL_II_USER_INCLUDE_DIRS}
)
CONFIGURE_FILE(
#
MACRO(FEATURE_BZIP2_FIND_EXTERNAL var)
-
FIND_PACKAGE(BZip2)
IF(BZIP2_FOUND)
#
- # Rename some variables:
+ # Rename variables:
#
SET(BZIP2_VERSION ${BZIP2_VERSION_STRING})
SET(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR})
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
MACRO(FEATURE_LAPACK_CONFIGURE_EXTERNAL)
- REGISTER_FEATURE(LAPACK)
CHECK_FOR_LAPACK_FUNCTIONS()
ENDMACRO()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
# Configuration for mpi support:
#
# We look for the C and Fortran libraries as well because they are needed
-# by some external libraries:
+# by some external libraries for the link interface:
#
MACRO(FEATURE_MPI_FIND_EXTERNAL var)
SET(${var} TRUE)
ENDIF()
+ # Hide some variables:
+ MARK_AS_ADVANCED(MPI_EXTRA_LIBRARY MPI_LIBRARY MPI_MPI_H)
+
#
# Populate correct variables:
#
SET(MPI_CXX_FLAGS ${MPI_CXX_COMPILE_FLAGS})
SET(MPI_LINKER_FLAGS "${MPI_CXX_LINK_FLAGS}")
- # Hide some variables:
- MARK_AS_ADVANCED(MPI_EXTRA_LIBRARY MPI_LIBRARY MPI_MPI_H)
-
-ENDMACRO()
-
-
-MACRO(FEATURE_MPI_CONFIGURE_EXTERNAL)
- #
- # The user has to know the location of the mpi headers as well:
- #
- SET(MPI_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
- REGISTER_FEATURE(MPI)
ENDMACRO()
CONFIGURE_FEATURE(MPI)
+
+#
+# The user has to know the location of the mpi headers as well:
+#
+SET(MPI_USER_INCLUDE_DIRS ${MPI_INCLUDE_DIRS})
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
# Unfortunately the FindThreads macro needs a working C compiler
#
IF(CMAKE_C_COMPILER_WORKS)
- #
- # Switch the library preference back to prefer dynamic libraries if
- # DEAL_II_PREFER_STATIC_LIBS=TRUE but DEAL_II_STATIC_EXECUTABLE=FALSE. In
- # this case system libraries should be linked dynamically.
- #
- SWITCH_LIBRARY_PREFERENCE()
-
#
# Clear the test flags because FindThreads.cmake will use a C compiler:
#
CLEAR_CMAKE_REQUIRED()
+ SWITCH_LIBRARY_PREFERENCE()
FIND_PACKAGE(Threads)
+ SWITCH_LIBRARY_PREFERENCE()
RESET_CMAKE_REQUIRED()
- SWITCH_LIBRARY_PREFERENCE()
ELSE()
IF(NOT Threads_FOUND)
#
- # TODO: This is a dead end. Threading might be setup with internal TBB
+ # TODO: This is a dead end. Threading might be set up with internal TBB
# so we have no way of returning unsuccessfully...
#
MESSAGE(FATAL_ERROR
ENDIF()
ENDIF()
- ADD_FLAGS(DEAL_II_LINKER_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
+ ADD_FLAGS(THREADS_LINKER_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
#
# Set up some posix thread specific configuration toggles:
MACRO(FEATURE_THREADS_CONFIGURE_EXTERNAL)
- REGISTER_FEATURE(TBB)
-
- # TODO: Refactor
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
IF(TBB_WITH_DEBUG_LIB)
- LIST(APPEND DEAL_II_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
- LIST(APPEND DEAL_II_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+ LIST(APPEND THREADS_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+ LIST(APPEND THREADS_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
ENDIF()
ENDIF()
IF( DEAL_II_WITH_CXX11 AND
NOT DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE AND
NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
- LIST(APPEND DEAL_II_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
- LIST(APPEND DEAL_II_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+ LIST(APPEND THREADS_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+ LIST(APPEND THREADS_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
ENDIF()
SETUP_THREADING()
- # TODO: Refactor this mess of a configure file...
- SET(THREADS_LIBRARIES ${TBB_LIBRARIES})
- SET(THREADS_INCLUDE_DIRS ${TBB_INCLUDE_DIRS})
+ LIST(APPEND THREADS_LIBRARIES ${TBB_LIBRARIES})
+ LIST(APPEND THREADS_INCLUDE_DIRS ${TBB_INCLUDE_DIRS})
ENDMACRO()
#
# We have to disable a bunch of warnings:
#
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-parentheses")
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-long-long")
+ ENABLE_IF_SUPPORTED(THREADS_CXX_FLAGS "-Wno-parentheses")
+ ENABLE_IF_SUPPORTED(THREADS_CXX_FLAGS "-Wno-long-long")
#
# Add some definitions to use the header files in debug mode:
#
IF (CMAKE_BUILD_TYPE MATCHES "Debug")
- LIST(APPEND DEAL_II_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
- LIST(APPEND DEAL_II_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+ LIST(APPEND THREADS_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+ LIST(APPEND THREADS_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
ENDIF()
#
IF( DEAL_II_WITH_CXX11 AND
NOT DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE AND
NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
- LIST(APPEND DEAL_II_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
- LIST(APPEND DEAL_II_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+ LIST(APPEND THREADS_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+ LIST(APPEND THREADS_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
ENDIF()
#
# tbb uses dlopen/dlclose, so link against libdl.so as well:
#
- FIND_LIBRARY(dl_LIBRARY NAMES dl)
+ # TODO: Also necessary for external lib, use preference toggle
+ #
+ FIND_SYSTEM_LIBRARY(dl_LIBRARY NAMES dl)
MARK_AS_ADVANCED(dl_LIBRARY)
IF(NOT dl_LIBRARY MATCHES "-NOTFOUND")
- LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${dl_LIBRARY})
+ LIST(APPEND THREADS_LIBRARIES ${dl_LIBRARY})
ENDIF()
- INCLUDE_DIRECTORIES(${TBB_FOLDER}/include)
+ LIST(APPEND THREADS_BUNDLED_INCLUDE_DIRS ${TBB_FOLDER}/include)
ENDMACRO()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
IF(DEAL_II_WITH_CXX11 AND NOT TRILINOS_SUPPORTS_CPP11)
IF(TRILINOS_HAS_C99_TR1_WORKAROUND)
- LIST(APPEND DEAL_II_DEFINITIONS "HAS_C99_TR1_CMATH")
- LIST(APPEND DEAL_II_USER_DEFINITIONS "HAS_C99_TR1_CMATH")
+ LIST(APPEND TRILINOS_DEFINITIONS "HAS_C99_TR1_CMATH")
+ LIST(APPEND TRILINOS_USER_DEFINITIONS "HAS_C99_TR1_CMATH")
ELSE()
MESSAGE(STATUS "Could not find a sufficient Trilinos installation: "
"The installation is not compatible with the C++ standard selected for "
MACRO(FEATURE_TRILINOS_CONFIGURE_EXTERNAL)
- SET(TRILINOS_ADD_TO_USER_INCLUDE_DIRS TRUE)
- REGISTER_FEATURE(TRILINOS)
+ SET(TRILINOS_USER_INCLUDE_DIRS ${TRILINOS_INCLUDE_DIRS})
SET(DEAL_II_EXPAND_TRILINOS_VECTOR "TrilinosWrappers::Vector")
SET(DEAL_II_EXPAND_TRILINOS_BLOCKVECTOR "TrilinosWrappers::BlockVector")
#
# Disable a bunch of warnings caused by Trilinos headers:
#
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-unused")
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-extra")
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-overloaded-virtual")
+ ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-unused")
+ ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-extra")
+ ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-overloaded-virtual")
ENDMACRO()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
SET(FEATURE_UMFPACK_DEPENDS DEAL_II_WITH_LAPACK)
MACRO(FEATURE_UMFPACK_CONFIGURE_BUNDLED)
- INCLUDE_DIRECTORIES(
+ SET(UMFPACK_BUNDLED_INCLUDE_DIRS
${UMFPACK_FOLDER}/UMFPACK/Include
${UMFPACK_FOLDER}/AMD/Include
)
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
MACRO(FEATURE_PETSC_CONFIGURE_EXTERNAL)
- INCLUDE_DIRECTORIES(${PETSC_INCLUDE_DIRS})
- SET(PETSC_ADD_TO_USER_INCLUDE_DIRS TRUE)
- REGISTER_FEATURE(PETSC)
+ SET(PETSC_USER_INCLUDE_DIRS ${PETSC_INCLUDE_DIRS})
#
# Disable a bunch of warnings when compiling with petsc:
#
- ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-long-long")
+ ENABLE_IF_SUPPORTED(PETSC_CXX_FLAGS "-Wno-long-long")
SET(DEAL_II_EXPAND_PETSC_VECTOR "PETScWrappers::Vector")
SET(DEAL_II_EXPAND_PETSC_BLOCKVECTOR "PETScWrappers::BlockVector")
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
ENDMACRO()
-#
-# The user has to know the location of the boost headers as well:
-#
-SET(BOOST_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
MACRO(FEATURE_BOOST_CONFIGURE_BUNDLED)
- INCLUDE_DIRECTORIES(${BOOST_FOLDER}/include)
+ SET(BOOST_BUNDLED_INCLUDE_DIRS ${BOOST_FOLDER}/include)
ENDMACRO()
CONFIGURE_FEATURE(BOOST)
+#
+# The user has to know the location of the boost headers as well:
+#
+SET(BOOST_USER_INCLUDE_DIRS ${BOOST_INCLUDE_DIRS})
+
#
# DEAL_II_WITH_BOOST is always required.
#
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
MACRO(FEATURE_FUNCTIONPARSER_CONFIGURE_BUNDLED)
- INCLUDE_DIRECTORIES(${FUNCTIONPARSER_FOLDER})
+ SET(FUNCTIONPARSER_BUNDLED_INCLUDE_DIRS ${FUNCTIONPARSER_FOLDER})
ENDMACRO()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
ENDMACRO()
+CONFIGURE_FEATURE(HDF5)
+
+
#
# The user has to know the location of the hdf5 headers as well:
#
-SET(HDF5_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(HDF5)
+SET(HDF5_USER_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
SET(FEATURE_MUMPS_DEPENDS DEAL_II_WITH_MPI DEAL_II_WITH_LAPACK)
+CONFIGURE_FEATURE(MUMPS)
+
#
# The user has to know the location of the MUMPS headers as well:
#
-SET(MUMPS_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(MUMPS)
+SET(MUMPS_USER_INCLUDE_DIRS ${MUMPS_INCLUDE_DIRS})
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
ENDMACRO()
+CONFIGURE_FEATURE(P4EST)
+
#
# The user has to know the location of the P4est headers as well:
#
-SET(P4EST_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(P4EST)
+SET(P4EST_USER_INCLUDE_DIRS ${P4EST_INCLUDE_DIRS})
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
ENDMACRO()
-#
-# The user has to know the location of the SLEPC headers as well:
-#
-SET(SLEPC_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
MACRO(FEATURE_SLEPC_ERROR_MESSAGE)
MESSAGE(FATAL_ERROR "\n"
"Could not find the SLEPc library!\n"
CONFIGURE_FEATURE(SLEPC)
+
+#
+# The user has to know the location of the SLEPC headers as well:
+#
+SET(SLEPC_USER_INCLUDE_DIRS ${SLEPC_INCLUDE_DIRS})
IF(FEATURE_${_feature}_HAVE_BUNDLED)
RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_BUNDLED()")
MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with bundled packages.")
+ LIST(APPEND DEAL_II_FEATURES ${_feature})
SET(FEATURE_${_feature}_BUNDLED_CONFIGURED TRUE)
SET_CACHED_OPTION(${_feature} ON)
ELSE()
IF(COMMAND FEATURE_${_feature}_CONFIGURE_EXTERNAL)
RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_EXTERNAL()")
- ELSE()
- REGISTER_FEATURE(${_feature})
ENDIF()
MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with external dependencies.")
+ LIST(APPEND DEAL_II_FEATURES ${_feature})
SET(FEATURE_${_feature}_EXTERNAL_CONFIGURED TRUE)
SET_CACHED_OPTION(${_feature} ON)
IF(FEATURE_${_feature}_HAVE_BUNDLED AND DEAL_II_ALLOW_BUNDLED)
RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_BUNDLED()")
+
MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with bundled packages.")
+ LIST(APPEND DEAL_II_FEATURES ${_feature})
SET(FEATURE_${_feature}_BUNDLED_CONFIGURED TRUE)
SET_CACHED_OPTION(${_feature} ON)
+
ELSE()
IF(DEAL_II_WITH_${_feature})
IF(COMMAND FEATURE_${_feature}_ERROR_MESSAGE)
)
SET_TARGET_PROPERTIES(${_library}.${_build_lowercase} PROPERTIES
- LINK_FLAGS "${DEAL_II_LINKER_FLAGS};${DEAL_II_LINKER_FLAGS_${_build}}"
+ LINK_FLAGS "${DEAL_II_LINKER_FLAGS} ${DEAL_II_LINKER_FLAGS_${_build}}"
COMPILE_DEFINITIONS "${DEAL_II_DEFINITIONS};${DEAL_II_DEFINITIONS_${_build}}"
COMPILE_FLAGS "${DEAL_II_CXX_FLAGS} ${DEAL_II_CXX_FLAGS_${_build}}"
LINKER_LANGUAGE "CXX"
--- /dev/null
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# This macro replaces absolute paths to system libraries with the
+# corresponding short name within the FEATURE_LIBRARIES(|_DEBUG|_RELEASE)
+# variables
+#
+# Usage:
+# FILTER_SYSTEM_LIBRARIES(feature)
+#
+
+MACRO(FILTER_SYSTEM_LIBRARIES _feature)
+ FOREACH(_variable
+ ${_feature}_LIBRARIES
+ ${_feature}_LIBRARIES_DEBUG
+ ${_feature}_LIBRARIES_RELEASE
+ )
+ IF(DEFINED ${_variable})
+ SET(_tmp_${_variable} ${${_variable}})
+ SET(${_variable} "")
+ FOREACH(_lib ${_tmp_${_variable}})
+ IF(_lib MATCHES "lib(c|quadmath|gfortran|m|rt|nsl|dl|pthread).so$")
+ string(REGEX REPLACE ".*lib([a-z]+).so$" "\\1" _lib ${_lib})
+ ENDIF()
+ LIST(APPEND ${_variable} ${_lib})
+ ENDFOREACH()
+ ENDIF()
+ ENDFOREACH()
+ENDMACRO()
--- /dev/null
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2013 - 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Search for a system library. In contrast to normal libraries we do this
+# purely via "-l<library name>" instead of selecting a full library path..
+#
+# USAGE:
+# FIND_SYSTEM_LIBRARY(variable NAMES [list of possible names])
+#
+
+MACRO(FIND_SYSTEM_LIBRARY)
+ SET(_argn ${ARGN})
+ LIST(GET _argn 0 _variable)
+ LIST(REMOVE_AT _argn 0 1)
+
+ if("${_variable}" MATCHES "^${_variable}$")
+ FOREACH(_arg ${_argn})
+ LIST(APPEND CMAKE_REQUIRED_LIBRARIES "-l${_arg}")
+ CHECK_CXX_COMPILER_FLAG("" ${_variable})
+ RESET_CMAKE_REQUIRED()
+
+ IF(${_variable})
+ UNSET(${_variable} CACHE)
+ SET(${_variable} ${_arg} CACHE STRING "A system library.")
+ SET(${_variable} ${_arg})
+ BREAK()
+ ELSE()
+ UNSET(${_variable} CACHE)
+ ENDIF()
+ ENDFOREACH()
+
+ IF(NOT _variable)
+ SET(${_variable} "${_variable}-NOTFOUND")
+ ENDIF()
+ ENDIF()
+ENDMACRO()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2013 by the deal.II authors
+## Copyright (C) 2013 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
#
# This macro will add
#
-# <FEATURE>_LIBRARIES
-# <FEATURE>_INCLUDE_DIRS(|_DEBUG|_RELEASE)
-# <FEATURE>_USER_INCLUDE_DIRS(|_DEBUG|_RELEASE)
+# <FEATURE>_LIBRARIES (respecting general, optimized, debug keyword)
+# <FEATURE>_LIBRARIES(_DEBUG|_RELEASE)
+# <FEATURE>_(|BUNDLED_|USER_)INCLUDE_DIRS
# <FEATURE>_DEFINITIONS(|_DEBUG|_RELEASE)
# <FEATURE>_USER_DEFINITIONS(|_DEBUG|_RELEASE)
# <FEATURE>_CXX_FLAGS(|_DEBUG|_RELEASE)
# to the corresponding DEAL_II_* variables
#
-
MACRO(REGISTER_FEATURE _feature)
- # variables for include directories:
- FOREACH(_var ${_feature}_INCLUDE_DIRS ${_feature}_INCLUDE_PATH)
- IF(DEFINED ${_var})
- INCLUDE_DIRECTORIES(${${_var}})
- IF(${_feature}_ADD_TO_USER_INCLUDE_DIRS)
- LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${${_var}})
- ENDIF()
- ENDIF()
- ENDFOREACH()
-
- # variables for linker flags:
- FOREACH(_var ${_feature}_LINKER_FLAGS ${_feature}_LINK_FLAGS)
- IF(DEFINED ${_var})
- ADD_FLAGS(DEAL_II_LINKER_FLAGS "${${_var}}")
- ENDIF()
- ENDFOREACH()
-
- # variables for compiler flags:
- FOREACH(_var ${_feature}_CXX_FLAGS ${_feature}_COMPILE_FLAGS)
- IF(DEFINED ${_var})
- ADD_FLAGS(DEAL_II_CXX_FLAGS "${${_var}}")
- ENDIF()
- ENDFOREACH()
IF(DEFINED ${_feature}_LIBRARIES)
#
# Add ${_feature}_LIBRARIES to
- # DEAL_II_EXTERNAL_LIBRARIES
- # DEAL_II_EXTERNAL_LIBRARIES_DEBUG
- # DEAL_II_EXTERNAL_LIBRARIES_RELEASE
+ # DEAL_II_LIBRARIES
+ # DEAL_II_LIBRARIES_DEBUG
+ # DEAL_II_LIBRARIES_RELEASE
# depending on the "optmized", "debug" or "general" keyword
#
SET(_toggle "general")
SET(_toggle "${_tmp}")
ELSE()
IF("${_toggle}" STREQUAL "general")
- LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${_tmp})
+ LIST(APPEND DEAL_II_LIBRARIES ${_tmp})
ELSEIF("${_toggle}" STREQUAL "debug")
- LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_DEBUG ${_tmp})
+ LIST(APPEND DEAL_II_LIBRARIES_DEBUG ${_tmp})
ELSEIF("${_toggle}" STREQUAL "optimized")
- LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_RELEASE ${_tmp})
+ LIST(APPEND DEAL_II_LIBRARIES_RELEASE ${_tmp})
ENDIF()
ENDIF()
ENDFOREACH()
ENDIF()
+ FOREACH(_var
+ LIBRARIES_DEBUG LIBRARIES_RELEASE
+ INCLUDE_DIRS BUNDLED_INCLUDE_DIRS USER_INCLUDE_DIRS
+ DEFINITIONS DEFINITIONS_DEBUG DEFINITIONS_RELEASE
+ USER_DEFINITIONS USER_DEFINITIONS_DEBUG USER_DEFINITIONS_RELEASE
+ )
+ IF(DEFINED ${_feature}_${_var})
+ LIST(APPEND DEAL_II_${_var} ${${_feature}_${_var}})
+ ENDIF()
+ ENDFOREACH()
+
+ FOREACH(_var
+ CXX_FLAGS CXX_FLAGS_DEBUG CXX_FLAGS_RELEASE
+ LINKER_FLAGS LINKER_FLAGS_DEBUG LINKER_FLAGS_RELEASE
+ )
+ IF(DEFINED ${_feature}_${_var})
+ ADD_FLAGS(DEAL_II_${_var} "${${_feature}_${_var}}")
+ ENDIF()
+ ENDFOREACH()
+
ENDMACRO()
SET(CMAKE_PREFIX_PATH ${_cmake_prefix_path_backup})
MARK_AS_ADVANCED(
- atlas_LIBRARY
- atlcblas_LIBRARY
- atllapack_LIBRARY
- blas_LIBRARY
- eigen_blas_LIBRARY
- f77blas_LIBRARY
- gslcblas_LIBRARY
- lapack_LIBRARY
- m_LIBRARY
- ptf77blas_LIBRARY
- ptlapack_LIBRARY
- refblas_LIBRARY
+ atlas_LIBRARY atlcblas_LIBRARY atllapack_LIBRARY blas_LIBRARY
+ eigen_blas_LIBRARY f77blas_LIBRARY gslcblas_LIBRARY lapack_LIBRARY
+ m_LIBRARY ptf77blas_LIBRARY ptlapack_LIBRARY refblas_LIBRARY
reflapack_LIBRARY
)
# If CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES is not available, do it
# unconditionally for the most common case (gfortran).
#
- # Switch the library preference back to prefer dynamic libraries if
- # DEAL_II_PREFER_STATIC_LIBS=TRUE but DEAL_II_STATIC_EXECUTABLE=FALSE. In
- # this case system libraries should be linked dynamically.
- #
SET(_fortran_libs ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES})
SET_IF_EMPTY(_fortran_libs gfortran m quadmath c)
- SWITCH_LIBRARY_PREFERENCE()
FOREACH(_lib ${_fortran_libs})
- FIND_LIBRARY(${_lib}_LIBRARY
- NAMES ${_lib}
- HINTS
- ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}
- ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
+ FIND_SYSTEM_LIBRARY(${_lib}_LIBRARY NAMES ${_lib})
MARK_AS_ADVANCED(${_lib}_LIBRARY)
IF(NOT ${_lib}_LIBRARY MATCHES "-NOTFOUND")
LIST(APPEND BLAS_LIBRARIES ${${_lib}_LIBRARY})
LIST(APPEND LAPACK_LIBRARIES ${${_lib}_LIBRARY})
ENDIF()
+
ENDFOREACH()
- SWITCH_LIBRARY_PREFERENCE()
#
# Filter out spurious "FALSE" in the library lists:
# Link line:
#
- FILE(STRINGS "${PETSC_PETSCVARIABLES}" _external_link_line
+ FILE(STRINGS "${PETSC_PETSCVARIABLES}" PETSC_EXTERNAL_LINK_LINE
REGEX "^PETSC_WITH_EXTERNAL_LIB =.*")
- SEPARATE_ARGUMENTS(_external_link_line)
+ SEPARATE_ARGUMENTS(PETSC_EXTERNAL_LINK_LINE)
+
+ IF(NOT "${PETSC_EXTERNAL_LINK_LINE}" STREQUAL "${PETSC_EXTERNAL_LINK_LINE_SAVED}")
+ SET(_new_petsc_external_link_line TRUE)
+ ENDIF()
+ SET(PETSC_EXTERNAL_LINK_LINE_SAVED "${PETSC_EXTERNAL_LINK_LINE}" CACHE INTERNAL "" FORCE)
SET(_hints)
SET(_petsc_libraries)
- FOREACH(_token ${_external_link_line}})
+ FOREACH(_token ${PETSC_EXTERNAL_LINK_LINE}})
IF(_token MATCHES "^-L")
# Build up hints with the help of all tokens passed with -L:
STRING(REGEX REPLACE "^-L" "" _token "${_token}")
ELSEIF(_token MATCHES "^-l")
# Search for every library that was specified with -l:
STRING(REGEX REPLACE "^-l" "" _token "${_token}")
- IF(NOT _token MATCHES "(petsc|stdc\\+\\+|gcc_s)")
+
+ IF(_new_petsc_external_link_line)
+ UNSET(PETSC_LIBRARY_${_token} CACHE)
+ ENDIF()
+
+ IF(_token MATCHES "^(c|quadmath|gfortran|m|rt|nsl|dl|pthread)$")
+ FIND_SYSTEM_LIBRARY(PETSC_LIBRARY_${_token} NAMES ${_token})
+ IF(NOT PETSC_LIBRARY_${_token} MATCHES "-NOTFOUND")
+ LIST(APPEND _petsc_libraries ${PETSC_LIBRARY_${_token}})
+ ENDIF()
+ ELSEIF(NOT _token MATCHES "(petsc|stdc\\+\\+|gcc_s)")
FIND_LIBRARY(PETSC_LIBRARY_${_token}
NAMES ${_token}
HINTS ${_hints}
IF(NOT PETSC_LIBRARY_${_token} MATCHES "-NOTFOUND")
LIST(APPEND _petsc_libraries ${PETSC_LIBRARY_${_token}})
ENDIF()
- #
- # Remove from cache, so that updating PETSC search paths will
- # find a (possibly) new link interface
- #
- UNSET(PETSC_LIBRARY_${_token} CACHE)
ENDIF()
+
ENDIF()
ENDFOREACH()
ENDIF()
-
-
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PETSC DEFAULT_MSG
PETSC_LIBRARY
PETSC_INCLUDE_DIR_ARCH
NO_SYSTEM_ENVIRONMENT_PATH
)
-IF(NOT "${TRILINOS_CONFIG}" STREQUAL "${TRILINOS_CONFIG_SAVED}")
+IF(NOT "${TRILINOS_CONFIG_DIR}" STREQUAL "${TRILINOS_CONFIG_DIR_SAVED}")
SET(_new_trilinos_config TRUE)
ENDIF()
-SET(TRILINOS_CONFIG_SAVED "${TRILINOS_CONFIG}" CACHE INTERNAL "" FORCE)
+SET(TRILINOS_CONFIG_DIR_SAVED "${TRILINOS_CONFIG_DIR}" CACHE INTERNAL "" FORCE)
#
"
TRILINOS_HAS_C99_TR1_WORKAROUND
)
-
RESET_CMAKE_REQUIRED()
-
MARK_AS_ADVANCED(TRILINOS_DIR)
ELSE()
SET(TRILINOS_LIBRARIES)
SET(TRILINOS_INCLUDE_DIRS)
- SET(TRILINOS_CONFIG_SAVED "" CACHE INTERNAL "" FORCE)
+ UNSET(TRILINOS_CONFIG_DIR_SAVED CACHE)
SET(TRILINOS_DIR "" CACHE PATH
"An optional hint to a Trilinos installation"
FIND_UMFPACK_LIBRARY(CAMD camd)
FIND_UMFPACK_LIBRARY(SuiteSparse_config suitesparseconfig)
+#
+# Test whether libsuitesparseconfig.xxx can be used for shared library
+# linkage. If not, exclude it from the command line.
+#
+LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ "-shared"
+ ${SuiteSparse_config_LIBRARY}
+ )
+CHECK_CXX_SOURCE_COMPILES("extern int SuiteSparse_version (int[3]);
+ void foo(int bar[3]) { SuiteSparse_version(bar);}"
+ LAPACK_SUITESPARSECONFIG_WITH_PIC
+ )
+RESET_CMAKE_REQUIRED()
+
IF(EXISTS ${UMFPACK_INCLUDE_DIR}/umfpack.h)
FILE(STRINGS "${UMFPACK_INCLUDE_DIR}/umfpack.h" UMFPACK_VERSION_MAJOR_STRING
REGEX "#define.*UMFPACK_MAIN_VERSION")
${COLAMD_LIBRARY}
${CAMD_LIBRARY}
${AMD_LIBRARY}
- ${SuiteSparse_config_LIBRARY}
)
+ IF(LAPACK_SUITESPARSECONFIG_WITH_PIC OR NOT BUILD_SHARED_LIBS)
+ LIST(APPEND UMFPACK_LIBRARIES ${SuiteSparse_config_LIBRARY})
+ ENDIF()
#
# For good measure:
# lib does not record its dependence on librt.so as evidenced
# by ldd :-( ):
#
- SWITCH_LIBRARY_PREFERENCE()
- FIND_LIBRARY(rt_LIBRARY NAMES rt)
- SWITCH_LIBRARY_PREFERENCE()
+ FIND_SYSTEM_LIBRARY(rt_LIBRARY NAMES rt)
MARK_AS_ADVANCED(rt_LIBRARY)
IF(NOT rt_LIBRARY MATCHES "-NOTFOUND")
LIST(APPEND UMFPACK_LIBRARIES ${rt_LIBRARY})
# Check the user provided CXX flags:
#
-IF( NOT "${DEAL_II_CXX_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_CXX_FLAGS_SAVED}"
- OR NOT "${DEAL_II_LINKER_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_LINKER_FLAGS_SAVED}")
+IF(NOT "${DEAL_II_CXX_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_CXX_FLAGS_SAVED}"
+ OR NOT "${DEAL_II_LINKER_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_LINKER_FLAGS_SAVED}")
MESSAGE(STATUS "")
# Rerun this test if cxx flags changed:
UNSET(DEAL_II_HAVE_USABLE_CXX_FLAGS CACHE)
+ELSE()
+ SET(DEAL_II_HAVE_USABLE_CXX_FLAGS TRUE CACHE INTERNAL "")
ENDIF()
SET(CACHED_DEAL_II_CXX_FLAGS_SAVED "${DEAL_II_CXX_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
SET(CACHED_DEAL_II_LINKER_FLAGS_SAVED "${DEAL_II_LINKER_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
#
# Sanity check: The variables defined in DEAL_II_REMOVED_FLAGS must not be
-# used during the comfiguration stage:
+# used during the configuration stage:
#
FOREACH(_flag ${DEAL_II_REMOVED_FLAGS})
IF(NOT "${_flag}" STREQUAL "")
ENDFOREACH()
#
-# Deduplicate entries in DEAL_II_USER_INCLUDE_DIRS
+# Deduplicate entries in *_INCLUDE_DIRS and *_LIBRARIES
#
-REMOVE_DUPLICATES(DEAL_II_USER_INCLUDE_DIRS)
+FOREACH(_feature DEAL_II ${DEAL_II_FEATURES})
+ FOREACH(_suffix INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS)
+ REMOVE_DUPLICATES(${_feature}_${_suffix})
+ ENDFOREACH()
+ FOREACH(_suffix LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG)
+ REMOVE_DUPLICATES(${_feature}_${_suffix} REVERSE)
+ ENDFOREACH()
+ENDFOREACH()
#
-# Deduplicate entries in DEAL_II_EXTERNAL_LIBRARIES(_...)
-# in reverse order:
+# Save base configuration into variables BASE_* for later use in
+# setup_write_config.cmake:
#
-REMOVE_DUPLICATES(DEAL_II_EXTERNAL_LIBRARIES REVERSE)
+FOREACH(_suffix
+ CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG
+ DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG
+ USER_DEFINITIONS USER_DEFINITIONS_RELEASE USER_DEFINITIONS_DEBUG
+ LINKER_FLAGS LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG
+ INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS
+ LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG
+ )
+ SET(BASE_${_suffix} ${DEAL_II_${_suffix}})
+ENDFOREACH()
-FOREACH(_build ${DEAL_II_BUILD_TYPES})
- REMOVE_DUPLICATES(DEAL_II_EXTERNAL_LIBRARIES_${_build} REVERSE)
+#
+# Register features:
+#
+FOREACH(_feature ${DEAL_II_FEATURES})
+ FILTER_SYSTEM_LIBRARIES(${_feature})
+ REGISTER_FEATURE(${_feature})
+ENDFOREACH()
+
+#
+# Deduplicate entries one more time :-]
+#
+FOREACH(_suffix INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS)
+ REMOVE_DUPLICATES(DEAL_II_${_suffix})
+ENDFOREACH()
+FOREACH(_suffix LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG)
+ REMOVE_DUPLICATES(DEAL_II_${_suffix} REVERSE)
ENDFOREACH()
#
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_${_build_lowercase}
)
ENDFOREACH()
-FILE(WRITE
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
- ""
- )
#
# Cleanup deal.IITargets.cmake in the build directory:
#
-FILE(WRITE
+FILE(REMOVE
${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
- ""
)
--- /dev/null
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+
+########################################################################
+# #
+# Sanity checks: #
+# #
+########################################################################
+
+#
+# A quick test whether we're able to successfully link with the given
+# compiler and linker flags and the given library link interface:
+#
+
+MESSAGE(STATUS "")
+MESSAGE(STATUS "Sanity checks.")
+
+FOREACH(_build ${DEAL_II_BUILD_TYPES})
+
+ FOREACH(_var
+ CXX_FLAGS CXX_FLAGS_${_build}
+ LINKER_FLAGS LINKER_FLAGS_${_build}
+ LIBRARIES LIBRARIES_${_build}
+ )
+ IF(NOT "${DEAL_II_${_var}}" STREQUAL "${CACHED_DEAL_II_${_var}_${_build}}")
+ UNSET(DEAL_II_SANITY_CHECK_${_build} CACHE)
+ SET(CACHED_DEAL_II_${_var}_${_build} "${DEAL_II_${_var}}" CACHE INTERNAL "" FORCE)
+ ENDIF()
+ ENDFOREACH()
+
+ RESET_CMAKE_REQUIRED()
+ ADD_FLAGS(CMAKE_REQUIRED_FLAGS
+ "${DEAL_II_CXX_FLAGS} ${DEAL_II_CXX_FLAGS_${_build}}"
+ )
+ LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ "${DEAL_II_LINKER_FLAGS} ${DEAL_II_CXX_LINKER_${_build}}"
+ )
+ LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ ${DEAL_II_LIBRARIES}
+ ${DEAL_II_LIBRARIES_${_build}}
+ )
+ CHECK_CXX_SOURCE_COMPILES("int main(){ return 0; }"
+ DEAL_II_SANITY_CHECK_${_build}
+ )
+ RESET_CMAKE_REQUIRED()
+
+ IF(NOT DEAL_II_SANITY_CHECK_${_build})
+ UNSET(DEAL_II_SANITY_CHECK_${_build} CACHE)
+ MESSAGE(FATAL_ERROR "
+ Configuration error: Cannot compile and link with the current set of
+ compiler flags, linker flags and libraries!
+
+ Please check the test output given at the end of
+ CMakeFiles/CMakeError.log and consult detailed.log for the current
+ configuration.\n\n"
+ )
+ ENDIF()
+ENDFOREACH()
## ---------------------------------------------------------------------
## $Id$
##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2014 by the deal.II authors
##
## This file is part of the deal.II library.
##
_both("#\n")
_detailed(
-"# Compiler flags used for this build:
-# DEAL_II_CXX_FLAGS: ${DEAL_II_CXX_FLAGS}
+"# Base configuration (prior to feature configuration):
+# DEAL_II_CXX_FLAGS: ${BASE_CXX_FLAGS}
"
)
IF(CMAKE_BUILD_TYPE MATCHES "Release")
- _detailed("# DEAL_II_CXX_FLAGS_RELEASE: ${DEAL_II_CXX_FLAGS_RELEASE}\n")
+ _detailed("# DEAL_II_CXX_FLAGS_RELEASE: ${BASE_CXX_FLAGS_RELEASE}\n")
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
- _detailed("# DEAL_II_CXX_FLAGS_DEBUG: ${DEAL_II_CXX_FLAGS_DEBUG}\n")
+ _detailed("# DEAL_II_CXX_FLAGS_DEBUG: ${BASE_CXX_FLAGS_DEBUG}\n")
ENDIF()
-_detailed("# DEAL_II_LINKER_FLAGS: ${DEAL_II_LINKER_FLAGS}\n")
+_detailed("# DEAL_II_LINKER_FLAGS: ${BASE_LINKER_FLAGS}\n")
IF(CMAKE_BUILD_TYPE MATCHES "Release")
- _detailed("# DEAL_II_LINKER_FLAGS_RELEASE: ${DEAL_II_LINKER_FLAGS_RELEASE}\n")
+ _detailed("# DEAL_II_LINKER_FLAGS_RELEASE: ${BASE_LINKER_FLAGS_RELEASE}\n")
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
- _detailed("# DEAL_II_LINKER_FLAGS_DEBUG: ${DEAL_II_LINKER_FLAGS_DEBUG}\n")
+ _detailed("# DEAL_II_LINKER_FLAGS_DEBUG: ${BASE_LINKER_FLAGS_DEBUG}\n")
ENDIF()
-_detailed("# DEAL_II_DEFINITIONS: ${DEAL_II_DEFINITIONS}\n")
+_detailed("# DEAL_II_DEFINITIONS: ${BASE_DEFINITIONS}\n")
IF(CMAKE_BUILD_TYPE MATCHES "Release")
- _detailed("# DEAL_II_DEFINITIONS_RELEASE: ${DEAL_II_DEFINITIONS_RELEASE}\n")
+ _detailed("# DEAL_II_DEFINITIONS_RELEASE: ${BASE_DEFINITIONS_RELEASE}\n")
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
- _detailed("# DEAL_II_DEFINITIONS_DEBUG: ${DEAL_II_DEFINITIONS_DEBUG}\n")
+ _detailed("# DEAL_II_DEFINITIONS_DEBUG: ${BASE_DEFINITIONS_DEBUG}\n")
+ENDIF()
+
+_detailed("# DEAL_II_USER_DEFINITIONS: ${BASE_DEFINITIONS}\n")
+IF(CMAKE_BUILD_TYPE MATCHES "Release")
+ _detailed("# DEAL_II_USER_DEFINITIONS_REL: ${BASE_DEFINITIONS_RELEASE}\n")
+ENDIF()
+IF(CMAKE_BUILD_TYPE MATCHES "Debug")
+ _detailed("# DEAL_II_USER_DEFINITIONS_DEB: ${BASE_DEFINITIONS_DEBUG}\n")
+ENDIF()
+
+_detailed("# DEAL_II_INCLUDE_DIRS ${BASE_INCLUDE_DIRS}\n")
+_detailed("# DEAL_II_USER_INCLUDE_DIRS: ${BASE_USER_INCLUDE_DIRS}\n")
+_detailed("# DEAL_II_BUNDLED_INCLUDE_DIRS: ${BASE_BUNDLED_INCLUDE_DIRS}\n")
+
+_detailed("# DEAL_II_LIBRARIES: ${BASE_LIBRARIES}\n")
+IF(CMAKE_BUILD_TYPE MATCHES "Release")
+ _detailed("# DEAL_II_LIBRARIES_RELEASE: ${BASE_LIBRARIES_RELEASE}\n")
+ENDIF()
+IF(CMAKE_BUILD_TYPE MATCHES "Debug")
+ _detailed("# DEAL_II_LIBRARIES_DEBUG: ${BASE_LIBRARIES_DEBUG}\n")
ENDIF()
_detailed("#\n")
FOREACH(_var ${_features})
IF(${${_var}})
- # FEATURE is enabled
+
+ #
+ # The feature is enabled:
+ #
STRING(REGEX REPLACE "^DEAL_II_WITH_" "" _feature ${_var})
IF(FEATURE_${_feature}_EXTERNAL_CONFIGURED)
_both("# ${_var} set up with external dependencies\n")
-
- #
- # Print out version number:
- #
- IF(DEFINED ${_feature}_VERSION)
- _detailed("# ${_feature}_VERSION = ${${_feature}_VERSION}\n")
- ENDIF()
-
- #
- # Special version numbers:
- #
- IF(_feature MATCHES "THREADS" AND DEFINED TBB_VERSION)
- _detailed("# TBB_VERSION = ${TBB_VERSION}\n")
- ENDIF()
- IF(_feature MATCHES "MPI" AND DEFINED OMPI_VERSION)
- _detailed("# OMPI_VERSION = ${OMPI_VERSION}\n")
- ENDIF()
-
- #
- # Print out ${_feature}_DIR:
- #
- IF(NOT "${${_feature}_DIR}" STREQUAL "")
- _detailed("# ${_feature}_DIR = ${${_feature}_DIR}\n")
- ENDIF()
-
- #
- # Print the feature configuration:
- #
- FOREACH(_var2
- CXX_COMPILER C_COMPILER Fortran_COMPILER LIBRARIES INCLUDE_DIRS
- USER_INCLUDE_DIRS DEFINITIONS USER_DEFINITIONS CXX_FLAGS
- LINKER_FLAGS
- )
- IF(DEFINED ${_feature}_${_var2})
- _detailed("# ${_feature}_${_var2} = ${${_feature}_${_var2}}\n")
- ENDIF()
- ENDFOREACH()
-
ELSEIF(FEATURE_${_feature}_BUNDLED_CONFIGURED)
-
IF(DEAL_II_FORCE_BUNDLED_${_feature})
_both("# ${_var} set up with bundled packages (forced)\n")
ELSE()
ELSE()
_both("# ${_var} = ${${_var}}\n")
ENDIF()
+
+ #
+ # Print out version number:
+ #
+ IF(DEFINED ${_feature}_VERSION)
+ _detailed("# ${_feature}_VERSION = ${${_feature}_VERSION}\n")
+ ENDIF()
+
+ #
+ # Special version numbers:
+ #
+ IF(_feature MATCHES "THREADS" AND DEFINED TBB_VERSION)
+ _detailed("# TBB_VERSION = ${TBB_VERSION}\n")
+ ENDIF()
+ IF(_feature MATCHES "MPI" AND DEFINED OMPI_VERSION)
+ _detailed("# OMPI_VERSION = ${OMPI_VERSION}\n")
+ ENDIF()
+
+ #
+ # Print out ${_feature}_DIR:
+ #
+ IF(NOT "${${_feature}_DIR}" STREQUAL "")
+ _detailed("# ${_feature}_DIR = ${${_feature}_DIR}\n")
+ ENDIF()
+
+ #
+ # Print the feature configuration:
+ #
+ FOREACH(_var2
+ C_COMPILER CXX_COMPILER Fortran_COMPILER
+ CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG
+ DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG
+ USER_DEFINITIONS USER_DEFINITIONS_RELEASE USER_DEFINITIONS_DEBUG
+ LINKER_FLAGS LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG
+ INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS
+ LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG
+ )
+ IF(DEFINED ${_feature}_${_var2})
+ _detailed("# ${_feature}_${_var2} = ${${_feature}_${_var2}}\n")
+ ENDIF()
+ ENDFOREACH()
ELSE()
# FEATURE is disabled
_both("# ( ${_var} = ${${_var}} )\n")
<code>FATAL_ERROR</code> must be avoided (the only exception is
the <code>REQUIRED</code> keyword).
<li>
- If successful, the following uncached variables might be set:
-
+ If the feature is successfully found, a subset of the following
+ <b>uncached</b> variables might be set:
<pre>
FEATURE_FOUND
-FEATURE_LIBRARIES
+FEATURE_LIBRARIES (with optimized, debug, release keywords)
+FEATURE_LIBRARIES(_DEBUG|_RELEASE)
FEATURE_INCLUDE_DIRS
-FEATURE_LINKER_FLAGS
+FEATURE_LINKER_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_CXX_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_DEFINITIONS(|_DEBUG|_RELEASE)
FEATURE_VERSION
-FEATURE_VERSION_MAJOR
-FEATURE_VERSION_MINOR
-FEATURE_VERSION_SUBMINOR
+FEATURE_VERSION(_MAJOR|_MINOR|_SUBMINOR)
</pre>
There are obviously valid exceptions from this rule, though.
"global" variables prefixed by <code>FEATURE_</code> may be
altered. Do not set <code>DEAL_II_*</code> or <code>CMAKE_*</code>
variables directly!
+
+ <li>
+ The find module must define a macro <code>FEATURE_CLEAR</code> that
+ unsets all cached variables, so that a subsequent call to the find
+ module starts a completely fresh features search.
<li>
A hint with <code>FEATURE_DIR</code> can be set up for
convenience. It is best to start the <code>Find</code> module by
module is used to determine whether an external dependency can be
resolved or not. Depending on the current state of
<code>DEAL_II_WITH_<FEATURE></code> (see
- <a href="../users/cmake.html#configurefeature">here</a>) the variables
+ <a href="../users/cmake.html#configurefeature">here</a>) the
+ configuration variables
<pre>
FEATURE_LIBRARIES
-FEATURE_INCLUDE_DIRS
-FEATURE_LINKER_FLAGS
+FEATURE_LIBRARIES(|_DEBUG|_RELEASE)
+FEATURE_(|USER_|BUNDLED_)INCLUDE_DIRS
+FEATURE_LINKER_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_CXX_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_DEFINITIONS(|_DEBUG|_RELEASE)
</pre>
are appended to the set of <a href="#variables">global variables</a>
and <code>DEAL_II_WITH_<FEATURE></code> is set to
</pre>
<li>
- In <code>./bundled/CMakeLists.txt</code>:
+ In <code>./bundled/configure_bundled.cmake</code>:
<pre>
FEATURE_<FEATURE>_HAVE_BUNDLED (a boolean)
- which should either be set to TRUE if all necessary libraries of the
<code>LIST(APPEND ...)</code>, flags with <code>ADD_FLAGS(...)</code>
(or if it is necessary to guard them with
<code>ENABLE_IF_SUPPORTED(...)</code>.)
+</p>
+<p>
+ <b>Feature configuration must not be added directly to this variables but
+ to corresponding <code><FEATURE>_*</code> variables, instead.
+ Feature configuration variables get appended to the below list of global
+ configuration variables automatically.</b>
+</p>
+
+
<ul>
<li>
The general (internal) logic for variables applies:
</ul>
<li>
- For internal use, for setting necessary linker flags for the deal.II library:
+ For internal and external use, used to keep track of external
+ libraries, the <acronym>deal.II</acronym> library and user
+ programs have to be linked against:
<ul>
- <li> <code>DEAL_II_LINKER_FLAGS</code>
- <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
- <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
+ <li> <code>DEAL_II_LIBRARIES</code>
+ <li> <code>DEAL_II_LIBRARIES_DEBUG</code>
+ <li> <code>DEAL_II_LIBRARIES_RELEASE</code>
</ul>
<li>
- For internal use, for setting necessary compiler flags, e.g.
- <code>-std=c++11</code> (if available):
+ For internal use, for setting necessary include dirs for the compilation of the
+ <acronym>deal.II</acronym> library:
<ul>
- <li> <code>DEAL_II_CXX_FLAGS</code>
- <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
- <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
+ <li> <code>DEAL_II_INCLUDE_DIRS</code>
</ul>
-
<li>
- For internal use, for setting necessary include dirs for the compilation of the
- <acronym>deal.II</acronym> library:
+ Used to keep track of external include dirs, necessary for the
+ compilation of user programs:
<ul>
- <li> <code>INCLUDE_DIRECTORIES(...)</code>
+ <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
+ </ul>
+ <li>
+ Include dirs from bundled packages necessary for the compilation fo
+ the library and user projects out of the build directory:
+ <ul>
+ <li> <code>DEAL_II_BUNDLED_INCLUDE_DIRS</code>
</ul>
<li>
<li> <code>DEAL_II_DEFINITIONS_DEBUG</code>
<li> <code>DEAL_II_DEFINITIONS_RELEASE</code>
</ul>
-
- <li>
- For internal and external use, used to keep track of external
- libraries, the <acronym>deal.II</acronym> library and user
- programs have to be linked against:
- <ul>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES</code>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES_DEBUG</code>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES_RELEASE</code>
- </ul>
-
<li>
For external use, used to keep track of external preprocessor
definitions, necessary for the compilation of user programs:
</ul>
<li>
- Used to keep track of external include dirs, necessary for the
- compilation of user programs:
+ For internal and external use, for setting necessary compiler flags,
+ e.g. <code>-std=c++11</code> (if available):
<ul>
- <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
+ <li> <code>DEAL_II_CXX_FLAGS</code>
+ <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
+ <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
</ul>
+
+ <li>
+ For internal use, for setting necessary linker flags for the deal.II library:
+ <ul>
+ <li> <code>DEAL_II_LINKER_FLAGS</code>
+ <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
+ <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
+ </ul>
+
</ul>
</p>
* is a vector of expension coefficients. Because we don't know their values
* yet (we will compute them as the solution of a linear or nonlinear system),
* they are called "unknowns" or "degrees of freedom". The second meaning of
- * the term con be explained as follows: A mathematical description of finite
+ * the term can be explained as follows: A mathematical description of finite
* element problem is often to say that we are looking for a finite
* dimensional function $u_h \in V_h$ that satisfies some set of equations
* (e.g. $a(u_h,\varphi_h)=(f,\varphi_h)$ for all test functions $\varphi_h\in
// ---------------------------------------------------------------------
/**
-// * @page changes_after_8_1 Changes after Version 8.1
+@page changes_after_8_1 Changes after Version 8.1
<p>
This is the list of changes made after the release of
</p>
<ol>
+ <li> Changed: The various classes generating graphical output, such
+ as DataOut or DataOutStack, are all derived from a common interface
+ class DataOutInterface which, in turn was derived from DataOutBase
+ through <i>private</i> inheritance. Because we frequently also
+ access the (public) members of this private base class this has tripped
+ up most every compiler we know of at one point or another. Furthermore,
+ because DataOutBase was a class that only defined static member functions
+ and had not member variables, there was really no reason for this
+ construct.
+ <br>
+ For these reasons, DataOutBase is now just a regular namespace and the
+ inheritance is gone. For the most part, this should not lead to any
+ incompatibilities except in cases where you accessed members of
+ DataOutBase through their derived classes. For example, it was possible
+ to write <code>DataOut@<2@>::Patch@<2,2@></code> even though the
+ <code>Patch</code> class is actually declared in DataOutBase. Since
+ the inheritance is now gone, this is no longer possible and one
+ actually has to write DataOutBase::Patch instead. Using this form
+ turns out to be compatible also with older versions of deal.II.
+ <br>
+ (Wolfgang Bangerth, 2014/02/01)
+ </li>
</ol>
<h3>Specific improvements</h3>
<ol>
+ <li>Changed: DerivativeApproximation used to be a class that only had
+ static members. It is now a namespace.
+ <br>
+ (Wolfgang Bangerth, 2014/02/08)
+
+ <li>New: ThreadLocalStorage::clear() clears out all objects allocated on the
+ current and all other threads.
+ <br>
+ (Wolfgang Bangerth, 2014/02/06)
+
+ <li>Fixed: A configuration error on Debian Testing where accidentally a
+ non-pic libSuiteSparse_config.a was picked up when building a shared
+ library up resulting in a link error.
+ <br>
+ (Matthias Maier, 2014/02/04)
+
+ <li> Changed: GridTools::transform() can now deal with meshes with hanging nodes.
+ <br>
+ (Timo Heister, 2014/02/04)
+ </li>
+
+ <li>Fixed: Calling FEValuesViews::Vector::get_function_curls() computed
+ wrong results in some cases (see https://code.google.com/p/dealii/issues/detail?id=182).
+ This is now fixed.
+ <br>
+ (Christoph Heiniger, Wolfgang Bangerth, 2014/02/03)
+
+ <li>Added: The class LAPACKFullMatrix now implements interfaces to
+ matrix-matrix multiplication. Also, LAPACKFullMatrix::apply_lu_factorization
+ now also operates on multiple right hand sides in form of another
+ LAPACKFullMatrix.
+ <br>
+ (Martin Kronbichler, 2014/02/03)
+
+ <li>Added: A sanity check for the full link interface at configure time.
+ Hopefully this prevents some people from compiling the whole library just
+ to hit a link error.
+ <br>
+ (Matthias Maier, 2014/02/01)
+
+ <li>Fixed: The build system does no longer record full paths to system
+ libraries but uses the appropriate short names instead.
+ <br>
+ (Matthias Maier, 2014/02/01)
+
+ <li>Reworked: External feature setup. Disabling a feature now cleans up
+ associated internal, cached variables. A per-feature linkage test now spots
+ common linking inconsistencies early in the configuration stage (and not
+ just after a complete compilation).
+ <br>
+ (Matthias Maier, 2014/02/01)
+
<li>New/fixed: The ParameterHandler::print_parameters_section
- method not worked for XML output. There is now a flag
+ method did not work for XML output. There is now a flag
include_top_level_elements which prints all higher
subsection elements, default is false.
For XML output setting this flag to true is required
<br>
Comput. Methods Appl. Mech. Engrg., vol. 271, pp. 69-85, 2014.
</li>
+
+ <li> J. Willems
+ <br>
+ <strong>Robust Multilevel Methods for General Symmetric Positive Definite Operators
+ </strong>
+ <br>
+ SIAM J. Numer. Anal. 52 (2014), no. 1, 103-124.
+ </li>
+
</ol>
<br>
<strong>Adaptive Finite Element Methods for Elliptic Problems with Discontinuous Coefficients</strong>
<br>
- SIAM J. Numer. Anal. 51 (2013), no. 6, 3106--3134.
+ SIAM J. Numer. Anal. 51 (2013), no. 6, 3106-3134.
</li>
<li> A. Bonito, R. Glowinski
<br>
<strong>Time-discrete higher order ALE formulations: Stability</strong>
<br>
- SIAM J. Numer. Anal., 51(1), 577--608, 2013.
+ SIAM J. Numer. Anal., 51(1), 577-608, 2013.
</li>
<li> A. Bonito, J. E. Pasciak
/* ---------------------------------------------------------------------
* $Id$
*
- * Copyright (C) 2001 - 2013 by the deal.II authors
+ * Copyright (C) 2001 - 2014 by the deal.II authors
*
* This file is part of the deal.II library.
*
// program we shall generate output (from this we will then also generate
// the suffix of the filename to which we write).
//
- // Regarding the output format, the <code>DataOutInterface</code> class
- // (which is a base class of <code>DataOut</code> through which we will
- // access its fields) provides an enumeration field
- // <code>OutputFormat</code>, which lists names for all supported output
+ // Regarding the output format, the DataOutBase namespace
+ // provides an enumeration field
+ // DataOutBase::OutputFormat which lists names for all supported output
// formats. At the time of writing of this program, the supported graphics
// formats are represented by the enum values <code>ucd</code>,
// <code>gnuplot</code>, <code>povray</code>, <code>eps</code>,
// <code>gmv</code>, <code>tecplot</code>, <code>tecplot_binary</code>,
- // <code>dx</code>, and <code>vtk</code>, but this list will certainly
+ // <code>dx</code>, <code>vtk</code>, etc, but this list will certainly
// grow over time. Now, within various functions of that base class, you
// can use values of this type to get information about these graphics
// formats (for example the default suffix used for files of each format),
class SolutionOutput : public EvaluationBase<dim>
{
public:
- SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format);
+ SolutionOutput (const std::string &output_name_base,
+ const DataOutBase::OutputFormat output_format);
virtual void operator () (const DoFHandler<dim> &dof_handler,
const Vector<double> &solution) const;
private:
- const std::string output_name_base;
- const typename DataOut<dim>::OutputFormat output_format;
+ const std::string output_name_base;
+ const DataOutBase::OutputFormat output_format;
};
template <int dim>
SolutionOutput<dim>::
- SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format)
+ SolutionOutput (const std::string &output_name_base,
+ const DataOutBase::OutputFormat output_format)
:
output_name_base (output_name_base),
output_format (output_format)
// After the description above, the function generating the actual output
// is now relatively straightforward. The only particularly interesting
// feature over previous example programs is the use of the
- // <code>DataOut::default_suffix</code> function, returning the usual
+ // DataOutBase::default_suffix function, returning the usual
// suffix for files of a given format (e.g. ".eps" for encapsulated
// postscript files, ".gnuplot" for Gnuplot files), and of the generic
// <code>DataOut::write</code> function with a second argument, which
// Also generate an evaluator which writes out the solution:
Evaluation::SolutionOutput<dim>
postprocessor2 (std::string("solution-")+solver_name,
- DataOut<dim>::gnuplot);
+ DataOutBase::gnuplot);
// Take these two evaluation objects and put them in a list...
std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
/* ---------------------------------------------------------------------
* $Id$
*
- * Copyright (C) 2002 - 2013 by the deal.II authors
+ * Copyright (C) 2002 - 2014 by the deal.II authors
*
* This file is part of the deal.II library.
*
<< std::ends;
std::ofstream out (filename.str().c_str());
- data_out.write (out, DataOut<dim>::gnuplot);
+ data_out.write (out, DataOutBase::gnuplot);
}
<< std::ends;
std::ofstream out (filename.str().c_str());
- data_out.write (out, DataOut<dim>::gnuplot);
+ data_out.write (out, DataOutBase::gnuplot);
}
x)$. Here, $U_j$ is a vector of expansion coefficients. Because we don't know
their values yet (we will compute them as the solution of a linear or
nonlinear system), they are called "unknowns" or "degrees of freedom". The
-second meaning of the term con be explained as follows: A mathematical
+second meaning of the term can be explained as follows: A mathematical
description of finite element problem is often to say that we are looking for
a finite dimensional function $u_h \in V_h$ that satisfies some set of equations
(e.g. $a(u_h,\varphi_h)=(f,\varphi_h)$ for all test functions $\varphi_h\in
// The next function is setting up all the variables that describe the linear
// finite element problem, such as the DoF handler, the matrices, and
// vectors. The difference to what we did in step-5 is only that we now also
-// have to take care of handing node constraints. These constraints are
+// have to take care of hanging node constraints. These constraints are
// handled almost transparently by the library, i.e. you only need to know
// that they exist and how to get them, but you do not have to know how they
// are formed or what exactly is done with them.
inverse_derivative->notify(e);
}
-
+
+ template <class VECTOR>
+ double
+ Newton<VECTOR>::threshold(const double thr)
+ {
+ const double t = assemble_threshold;
+ assemble_threshold = thr;
+ return t;
+ }
+
+
template <class VECTOR>
void
Newton<VECTOR>::operator() (NamedData<VECTOR *> &out, const NamedData<VECTOR *> &in)
class ParameterHandler;
class XDMFEntry;
-class DataOutFilter;
/**
* This is a base class for output of data on meshes of very general
*
* <h3>DataOutBaseInterface</h3>
*
- * This class has an interface that is not usually called by a user
- * directly; also, it consists of <tt>static</tt> functions
- * only. Usually, derived classes will inherit this class
- * <tt>protected</tt> to hide this interface to the users of thes
- * classes.
+ * The members of this namespace are not usually called from user code
+ * directly. Rather, classes that use the functions declared here
+ * are typically derived from DataOutInterface.
*
* The interface of this class basically consists of the declaration of a data
* type describing a patch and a bunch of functions taking a list of patches
* @ingroup output
* @author Wolfgang Bangerth, Guido Kanschat 1999, 2000, 2001, 2002, 2005, 2006.
*/
-class DataOutBase
+namespace DataOutBase
{
-public:
/**
* Data structure describing a patch of data in <tt>dim</tt> space
* dimensions.
* understand.
*/
static const unsigned int format_version = 3;
-
+
private:
/**
* Dummy entry to suppress compiler warnings when copying an empty
* <tt>contrib/dx</tt>.
*/
template <int dim, int spacedim>
- static void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const DXFlags &flags,
- std::ostream &out);
+ void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const DXFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in eps format.
* class. See there for more and detailed information.
*/
template <int dim, int spacedim>
- static void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const EpsFlags &flags,
- std::ostream &out);
+ void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const EpsFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in
* space is interpolated to (bi-,tri-)linear elements.
*/
template <int dim, int spacedim>
- static void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const GmvFlags &flags,
- std::ostream &out);
+ void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const GmvFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in gnuplot
* cut-surface are plotted.
*/
template <int dim, int spacedim>
- static void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const GnuplotFlags &flags,
- std::ostream &out);
+ void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const GnuplotFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream for the
* included in the povray options.
*/
template <int dim, int spacedim>
- static void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const PovrayFlags &flags,
- std::ostream &out);
+ void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const PovrayFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in
* manuals.
*/
template <int dim, int spacedim>
- static void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const TecplotFlags &flags,
- std::ostream &out);
+ void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const TecplotFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in
* manuals.
*/
template <int dim, int spacedim>
- static void write_tecplot_binary (
+ void write_tecplot_binary (
const std::vector<Patch<dim,spacedim> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
* patch to the same value.
*/
template <int dim, int spacedim>
- static void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const UcdFlags &flags,
- std::ostream &out);
+ void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const UcdFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in VTK
* latter file format instead, by using the write_vtu() function.
*/
template <int dim, int spacedim>
- static void write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out);
+ void write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out);
/**
* The use of this function is explained in step-40.
*/
template <int dim, int spacedim>
- static void write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out);
+ void write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out);
/**
* This writes the header for the xml based vtu file format. This
* DataOutInterface::write_vtu_footer() and DataOutInterface::write_vtu_main()
* by DataOutBase::write_vtu().
*/
- static void write_vtu_header (std::ostream &out,
- const VtkFlags &flags);
+ void write_vtu_header (std::ostream &out,
+ const VtkFlags &flags);
/**
* This writes the footer for the xml based vtu file format. This
* DataOutInterface::write_vtu_header() and DataOutInterface::write_vtu_main()
* by DataOutBase::write_vtu().
*/
- static void write_vtu_footer (std::ostream &out);
+ void write_vtu_footer (std::ostream &out);
/**
* This writes the main part for the xml based vtu file format. This
* by DataOutBase::write_vtu().
*/
template <int dim, int spacedim>
- static void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out);
+ void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in SVG format.
* the data values at the vertices taken from the specified data
* vector. A colorbar can be drawn to encode the coloring.
*
- * @note Yet only implemented for two dimensions with an additional
- * dimension reserved for data information.
+ * @note This function is so far only implemented for two dimensions
+ * with an additional dimension reserved for data information.
*/
- template <int dim, int spacedim>
- static void write_svg (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const SvgFlags &flags,
- std::ostream &out);
+ template <int spacedim>
+ void write_svg (const std::vector<Patch<2,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const SvgFlags &flags,
+ std::ostream &out);
/**
* Write the given list of patches to the output stream in deal.II
* the ending <tt>.d2</tt>.
*/
template <int dim, int spacedim>
- static void write_deal_II_intermediate (
+ void write_deal_II_intermediate (
const std::vector<Patch<dim,spacedim> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
* the mesh and solution values.
*/
template <int dim, int spacedim>
- static void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
- const DataOutFilter &data_filter,
- const std::string &filename,
- MPI_Comm comm);
+ void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
+ const DataOutFilter &data_filter,
+ const std::string &filename,
+ MPI_Comm comm);
/**
* Write the data in data_filter to HDF5 file(s). If write_mesh_file
* contain both mesh data and solution values.
*/
template <int dim, int spacedim>
- static void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
- const DataOutFilter &data_filter,
- const bool write_mesh_file,
- const std::string &mesh_filename,
- const std::string &solution_filename,
- MPI_Comm comm);
+ void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
+ const DataOutFilter &data_filter,
+ const bool write_mesh_file,
+ const std::string &mesh_filename,
+ const std::string &solution_filename,
+ MPI_Comm comm);
/**
* DataOutFilter is an intermediate data format that reduces the amount of
* see, for example, DataOutBase::write_hdf5_parallel().
*/
template <int dim, int spacedim>
- static void write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- DataOutFilter &filtered_data);
+ void write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ DataOutFilter &filtered_data);
/**
* Given an input stream that contains data written by
* 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);
* string. If the string does not match any known format, an
* exception is thrown.
*
- * Since this function does not need data from this object, it is
- * static and can thus be called without creating an object of this
- * class. Its main purpose is to allow a program to use any
+ * The main purpose of this function is to allow a program to use any
* implemented output format without the need to extend the
* program's parser each time a new format is implemented.
*
* it to the ParameterHandler class, use the function
* get_output_format_names().
*/
- static OutputFormat parse_output_format (const std::string &format_name);
+ OutputFormat parse_output_format (const std::string &format_name);
/**
* Return a list of implemented output formats. The different names
* are separated by vertical bar signs (<tt>`|'</tt>) as used by the
* ParameterHandler classes.
*/
- static std::string get_output_format_names ();
+ std::string get_output_format_names ();
/**
* Provide a function which tells us which suffix a file with a
* <li> <tt>deal_II_intermediate</tt>: <tt>.d2</tt>.
* </ul>
*/
- static std::string default_suffix (const OutputFormat output_format);
-
- /**
- * Determine an estimate for the memory consumption (in bytes) of
- * this object. Since sometimes the size of objects can not be
- * determined exactly (for example: what is the memory consumption
- * of an STL <tt>std::map</tt> type with a certain number of
- * elements?), this is only an estimate. however often quite close
- * to the true value.
- */
- static std::size_t memory_consumption ();
+ std::string default_suffix (const OutputFormat output_format);
/** @addtogroup Exceptions
* @{ */
<< " for output");
//@}
-private:
- /**
- * Write the coordinates of nodes in the desired format.
- */
- template <int dim, int spacedim, typename STREAM>
- static void write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
- STREAM &out);
-
- /**
- * Write the node numbers of a cell in the desired format.
- */
- template <int dim, int spacedim, typename STREAM>
- static void write_cells (const std::vector<Patch<dim,spacedim> > &patches,
- STREAM &out);
-
- /**
- * Write data in the desired format.
- */
- template <int dim, int spacedim, class STREAM>
- static void write_data (const std::vector<Patch<dim,spacedim> > &patches,
- const unsigned int n_data_sets,
- const bool double_precision,
- STREAM &out);
-
-
- /**
- * This function projects a three-dimensional point (Point<3> point)
- * onto a two-dimensional image plane, specified by the position of
- * the camera viewing system (Point<3> camera_position), camera
- * direction (Point<3> camera_position), camera horizontal (Point<3>
- * camera_horizontal, necessary for the correct alignment of the
- * later images), and the focus of the camera (float camera_focus).
- *
- * For SVG output.
- */
- static Point<2> svg_project_point(Point<3> point,
- Point<3> camera_position,
- Point<3> camera_direction,
- Point<3> camera_horizontal,
- float camera_focus);
- /**
- * Function to compute the gradient parameters for a triangle with
- * given values for the vertices.
- *
- * Used for svg output.
- */
- static Point<6> svg_get_gradient_parameters(Point<3> points[]);
-
- /**
- * Class holding the data of one cell of a patch in two space
- * dimensions for output. It is the projection of a cell in
- * three-dimensional space (two coordinates, one height value) to
- * the direction of sight.
- */
- class SvgCell
- {
- public:
-
- // Center of the cell (three-dimensional)
- Point<3> center;
-
- /**
- * Vector of vertices of this cell (three-dimensional)
- */
- Point<3> vertices[4];
-
- /**
- * Depth into the picture, which is defined as the distance from
- * an observer at an the origin in direction of the line of sight.
- */
- float depth;
-
- /**
- * Vector of vertices of this cell (projected, two-dimensional).
- */
- Point<2> projected_vertices[4];
-
- // Center of the cell (projected, two-dimensional)
- Point<2> projected_center;
-
- /**
- * Comparison operator for sorting.
- */
- bool operator < (const SvgCell &) const;
- };
-
-
- /**
- * Class holding the data of one cell of a patch in two space
- * dimensions for output. It is the projection of a cell in
- * three-dimensional space (two coordinates, one height value) to
- * the direction of sight.
- */
- class EpsCell2d
- {
- public:
-
- /**
- * Vector of vertices of this cell.
- */
- Point<2> vertices[4];
-
- /**
- * Data value from which the actual colors will be computed by the
- * colorization function stated in the <tt>EpsFlags</tt> class.
- */
- float color_value;
-
- /**
- * Depth into the picture, which is defined as the distance from
- * an observer at an the origin in direction of the line of sight.
- */
- float depth;
-
- /**
- * Comparison operator for sorting.
- */
- bool operator < (const EpsCell2d &) const;
- };
-
-
- /**
- * This is a helper function for the write_gmv() function. There,
- * the data in the patches needs to be copied around as output is
- * one variable globally at a time, rather than all data on each
- * vertex at a time. This copying around can be done detached from
- * the main thread, and is thus moved into this separate function.
- *
- * Note that because of the similarity of the formats, this function
- * is also used by the Vtk and Tecplot output functions.
- */
- template <int dim, int spacedim>
- static void
- write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
- Table<2,double> &data_vectors);
-
-
-
-};
+}
/**
- * This class is the interface to the <tt>DataOutBase</tt> class, as already its name
+ * This class is the interface to the functions in the DataOutBase namespace, as already its name
* might suggest. It does not offer much functionality apart from a way to
* access the implemented formats and a way to dynamically dispatch what output
* format to chose.
* @author Wolfgang Bangerth, 1999
*/
template <int dim, int spacedim=dim>
-class DataOutInterface : private DataOutBase
+class DataOutInterface
{
public:
- /*
- * Import a few names that were
- * previously in this class and have then
- * moved to the base class. Since the
- * base class is inherited from
- * privately, we need to re-import these
- * symbols to make sure that references
- * to DataOutInterface<dim,spacedim>::XXX
- * remain valid.
- */
- using DataOutBase::OutputFormat;
- using DataOutBase::default_format;
- using DataOutBase::dx;
- using DataOutBase::gnuplot;
- using DataOutBase::povray;
- using DataOutBase::eps;
- using DataOutBase::tecplot;
- using DataOutBase::tecplot_binary;
- using DataOutBase::vtk;
- using DataOutBase::vtu;
- using DataOutBase::deal_II_intermediate;
- using DataOutBase::parse_output_format;
- using DataOutBase::get_output_format_names;
- using DataOutBase::determine_intermediate_format_dimensions;
-
- using DataOutBase::Patch;
-
/**
* Constructor.
*/
* the mesh and solution data were written to a single file. See
* write_xdmf_file() for an example of usage.
*/
- XDMFEntry create_xdmf_entry (const DataOutFilter &data_filter,
+ XDMFEntry create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
const std::string &h5_filename,
const double cur_time,
MPI_Comm comm) const;
* the mesh and solution data were written to separate files. See
* write_xdmf_file() for an example of usage.
*/
- XDMFEntry create_xdmf_entry (const DataOutFilter &data_filter,
+ XDMFEntry create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
const std::string &h5_mesh_filename,
const std::string &h5_solution_filename,
const double cur_time,
* single HDF5 file containing both the mesh and solution values.
@deprecated: use write_hdf5_parallel(DataOutFilter, ...) instead
*/
- void write_hdf5_parallel (const std::string &filename, MPI_Comm comm) const DEAL_II_DEPRECATED;
+ void write_hdf5_parallel (const std::string &filename,
+ MPI_Comm comm) const DEAL_II_DEPRECATED;
/**
* Write the data in data_filter to a single HDF5 file containing both
* data_out.write_hdf5_parallel(data_filter, "solution.h5", MPI_COMM_WORLD);
* @endcode
*/
- void write_hdf5_parallel (const DataOutFilter &data_filter, const std::string &filename, MPI_Comm comm) const;
+ void write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+ const std::string &filename, MPI_Comm comm) const;
/**
* Write the data in data_filter to HDF5 file(s). If write_mesh_file
* is true and the filenames are the same, the resulting file will
* contain both mesh data and solution values.
*/
- void write_hdf5_parallel (const DataOutFilter &data_filter, const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const;
+ void write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+ const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const;
/**
* DataOutFilter is an intermediate data format that reduces the amount of
* can then later be used again to write data in a concrete file format;
* see, for example, DataOutBase::write_hdf5_parallel().
*/
- void write_filtered_data (DataOutFilter &filtered_data) const;
+ void write_filtered_data (DataOutBase::DataOutFilter &filtered_data) const;
/**
* format is <tt>default_format</tt>.
*/
void write (std::ostream &out,
- const OutputFormat output_format = default_format) const;
+ const DataOutBase::OutputFormat output_format = DataOutBase::default_format) const;
/**
* Set the default format. The value set here is used anytime,
* output for format <tt>default_format</tt> is requested.
*/
- void set_default_format (const OutputFormat default_format);
+ void set_default_format (const DataOutBase::OutputFormat default_format);
/**
* Set the flags to be used for output in OpenDX format.
*/
- void set_flags (const DXFlags &dx_flags);
+ void set_flags (const DataOutBase::DXFlags &dx_flags);
/**
* Set the flags to be used for output in UCD format.
*/
- void set_flags (const UcdFlags &ucd_flags);
+ void set_flags (const DataOutBase::UcdFlags &ucd_flags);
/**
* Set the flags to be used for output in GNUPLOT format.
*/
- void set_flags (const GnuplotFlags &gnuplot_flags);
+ void set_flags (const DataOutBase::GnuplotFlags &gnuplot_flags);
/**
* Set the flags to be used for output in POVRAY format.
*/
- void set_flags (const PovrayFlags &povray_flags);
+ void set_flags (const DataOutBase::PovrayFlags &povray_flags);
/**
* Set the flags to be used for output in EPS output.
*/
- void set_flags (const EpsFlags &eps_flags);
+ void set_flags (const DataOutBase::EpsFlags &eps_flags);
/**
* Set the flags to be used for output in GMV format.
*/
- void set_flags (const GmvFlags &gmv_flags);
+ void set_flags (const DataOutBase::GmvFlags &gmv_flags);
/**
* Set the flags to be used for output in Tecplot format.
*/
- void set_flags (const TecplotFlags &tecplot_flags);
+ void set_flags (const DataOutBase::TecplotFlags &tecplot_flags);
/**
* Set the flags to be used for output in VTK format.
*/
- void set_flags (const VtkFlags &vtk_flags);
+ void set_flags (const DataOutBase::VtkFlags &vtk_flags);
/**
* Set the flags to be used for output in SVG format.
*/
- void set_flags (const SvgFlags &svg_flags);
+ void set_flags (const DataOutBase::SvgFlags &svg_flags);
/**
* Set the flags to be used for output in deal.II intermediate
* format.
*/
- void set_flags (const Deal_II_IntermediateFlags &deal_II_intermediate_flags);
+ void set_flags (const DataOutBase::Deal_II_IntermediateFlags &deal_II_intermediate_flags);
/**
* A function that returns the same string as the respective
* calling this function.
*/
std::string
- default_suffix (const OutputFormat output_format = default_format) const;
+ default_suffix (const DataOutBase::OutputFormat output_format = DataOutBase::default_format) const;
/**
* Declare parameters for all output formats by declaring
* functions to know what they shall print.
*/
virtual
- const std::vector<typename DataOutBase::Patch<dim,spacedim> > &
+ const std::vector<DataOutBase::Patch<dim,spacedim> > &
get_patches () const = 0;
/**
* default_format is requested. It can be changed by the
* <tt>set_format</tt> function or in a parameter file.
*/
- OutputFormat default_fmt;
+ DataOutBase::OutputFormat default_fmt;
/**
* Flags to be used upon output of OpenDX data. Can be changed by
* using the <tt>set_flags</tt> function.
*/
- DXFlags dx_flags;
+ DataOutBase::DXFlags dx_flags;
/**
* Flags to be used upon output of UCD data. Can be changed by using
* the <tt>set_flags</tt> function.
*/
- UcdFlags ucd_flags;
+ DataOutBase::UcdFlags ucd_flags;
/**
* Flags to be used upon output of GNUPLOT data. Can be changed by
* using the <tt>set_flags</tt> function.
*/
- GnuplotFlags gnuplot_flags;
+ DataOutBase::GnuplotFlags gnuplot_flags;
/**
* Flags to be used upon output of POVRAY data. Can be changed by
* using the <tt>set_flags</tt> function.
*/
- PovrayFlags povray_flags;
+ DataOutBase::PovrayFlags povray_flags;
/**
* Flags to be used upon output of EPS data in one space
* dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- EpsFlags eps_flags;
+ DataOutBase::EpsFlags eps_flags;
/**
* Flags to be used upon output of gmv data in one space
* dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- GmvFlags gmv_flags;
+ DataOutBase::GmvFlags gmv_flags;
/**
* Flags to be used upon output of Tecplot data in one space
* dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- TecplotFlags tecplot_flags;
+ DataOutBase::TecplotFlags tecplot_flags;
/**
* Flags to be used upon output of vtk data in one space
* dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- VtkFlags vtk_flags;
+ DataOutBase::VtkFlags vtk_flags;
/**
* Flags to be used upon output of svg data in one space
* dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- SvgFlags svg_flags;
+ DataOutBase::SvgFlags svg_flags;
/**
* Flags to be used upon output of deal.II intermediate data in one
* space dimension. Can be changed by using the <tt>set_flags</tt>
* function.
*/
- Deal_II_IntermediateFlags deal_II_intermediate_flags;
+ DataOutBase::Deal_II_IntermediateFlags deal_II_intermediate_flags;
};
* It returns the patches as read the last time a stream was given
* to the read() function.
*/
- virtual const std::vector<typename dealii::DataOutBase::Patch<dim,spacedim> > &
+ virtual const std::vector<dealii::DataOutBase::Patch<dim,spacedim> > &
get_patches () const;
/**
* Arrays holding the set of patches as well as the names of output
* variables, all of which we read from an input stream.
*/
- std::vector<typename dealii::DataOutBase::Patch<dim,spacedim> > patches;
+ std::vector<dealii::DataOutBase::Patch<dim,spacedim> > patches;
std::vector<std::string> dataset_names;
/**
/* -------------------- inline functions ------------------- */
-inline
-bool
-DataOutBase::EpsFlags::RgbValues::is_grey () const
+namespace DataOutBase
{
- return (red == green) && (red == blue);
-}
-
+ inline
+ bool
+ EpsFlags::RgbValues::is_grey () const
+ {
+ return (red == green) && (red == blue);
+ }
-/* -------------------- template functions ------------------- */
-/**
- * Output operator for an object of type
- * <tt>DataOutBase::Patch</tt>. This operator dumps the intermediate
- * graphics format represented by the patch data structure. It may
- * later be converted into regular formats for a number of graphics
- * programs.
- *
- * @author Wolfgang Bangerth, 2005
- */
-template <int dim, int spacedim>
-std::ostream &
-operator << (std::ostream &out,
- const DataOutBase::Patch<dim,spacedim> &patch);
+ /* -------------------- template functions ------------------- */
+ /**
+ * Output operator for an object of type
+ * <tt>DataOutBase::Patch</tt>. This operator dumps the intermediate
+ * graphics format represented by the patch data structure. It may
+ * later be converted into regular formats for a number of graphics
+ * programs.
+ *
+ * @author Wolfgang Bangerth, 2005
+ */
+ template <int dim, int spacedim>
+ std::ostream &
+ operator << (std::ostream &out,
+ const Patch<dim,spacedim> &patch);
-/**
- * Input operator for an object of type
- * <tt>DataOutBase::Patch</tt>. This operator reads the intermediate
- * graphics format represented by the patch data structure, using the
- * format in which it was written using the operator<<.
- *
- * @author Wolfgang Bangerth, 2005
- */
-template <int dim, int spacedim>
-std::istream &
-operator >> (std::istream &in,
- DataOutBase::Patch<dim,spacedim> &patch);
+ /**
+ * Input operator for an object of type
+ * <tt>DataOutBase::Patch</tt>. This operator reads the intermediate
+ * graphics format represented by the patch data structure, using the
+ * format in which it was written using the operator<<.
+ *
+ * @author Wolfgang Bangerth, 2005
+ */
+ template <int dim, int spacedim>
+ std::istream &
+ operator >> (std::istream &in,
+ Patch<dim,spacedim> &patch);
+}
DEAL_II_NAMESPACE_CLOSE
* <tt>values</tt> already has the right size, i.e. the same size as the
* <tt>points</tt> array.
*
- * Be default, this function repeatedly calls value() for each point
+ * By default, this function repeatedly calls value() for each point
* separately, to fill the output array.
*/
virtual void value_list (const std::vector<Point<dim> > &points,
* all elements be vectors with the same number of components as this
* function has.
*
- * Be default, this function repeatedly calls vector_value() for each
+ * By default, this function repeatedly calls vector_value() for each
* point separately, to fill the output array.
*/
virtual void vector_value_list (const std::vector<Point<dim> > &points,
// Define the expressions of the individual components of a
// vector valued function with two components:
std::vector<std::string> expressions(1);
- expressions[0] = "x cm + y m + PI cm;
+ expressions[0] = "x cm + y m + PI cm";
// Generate an empty function for these two components.
FunctionParser<2> vector_function;
-
+// The following function is not strictly necessary but is an optimization
+// for places where you call swap(p1,p2) with SmartPointer objects p1, p2.
+// Unfortunately, MS Visual Studio (at least up to the 2013 edition) trips
+// over it when calling std::swap(v1,v2) where v1,v2 are std::vectors of
+// SmartPointer objects: it can't determine whether it should call std::swap
+// or dealii::swap on the individual elements (see bug #184 on our Google Code
+// site. Consequently, just take this function out of the competition for this
+// compiler.
+#ifndef _MSC_VER
/**
* Global function to swap the contents of two smart pointers. As both
* objects to which the pointers point retain to be subscribed to, we
{
t1.swap (t2);
}
-
+#endif
/**
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2011 - 2013 by the deal.II authors
+// Copyright (C) 2011 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
/**
* Copy constructor. Initialize each thread local object
* with the corresponding object of the given object.
- **/
+ */
ThreadLocalStorage (const ThreadLocalStorage<T> &t);
/**
ThreadLocalStorage<T> &operator = (const T &t);
/**
- * Returns a reference to the internal implementation.
+ * Remove the thread-local objects stored for all threads that have
+ * created one with this object (i.e., that have called get()
+ * at least once on this thread. This includes the current thread. If you
+ * call get() subsequently on this or any other thread, new objects will
+ * again be created.
+ *
+ * If deal.II has been configured to not use multithreading, then this function
+ * does not do anything at all. Note that this of course has different semantics
+ * as in the multithreading context the objects are deleted and created again
+ * (possible by copying from a sample object, if the appropriate constructor
+ * of this class was called), whereas in the multithreaded context the object
+ * is simply not touched at all. At the same time, the purpose of this function
+ * is to release memory other threads may have allocated for their own thread
+ * local objects after which every use of this object will require some kind
+ * of initialization. This is necessary both in the multithreaded or
+ * non-multithreaded case.
+ */
+ void clear ();
+
+ /**
+ * Returns a reference to the internal Threading Building Blocks
+ * implementation. This function is really only useful if deal.II
+ * has been configured with multithreading and has no useful
+ * purpose otherwise.
*/
#ifdef DEAL_II_WITH_THREADS
tbb::enumerable_thread_specific<T> &
#else
T &
#endif
- get_implementation()
- {
- return data;
- }
+ get_implementation();
private:
#ifdef DEAL_II_WITH_THREADS
get() = t;
return *this;
}
+
+
+ template <typename T>
+ inline
+#ifdef DEAL_II_WITH_THREADS
+ tbb::enumerable_thread_specific<T> &
+#else
+ T &
+#endif
+ ThreadLocalStorage<T>::get_implementation()
+ {
+ return data;
+ }
+
+
+
+ template <typename T>
+ inline
+ void
+ ThreadLocalStorage<T>::clear ()
+ {
+#ifdef DEAL_II_WITH_THREADS
+ data.clear ();
+#endif
+ }
} // end of implementation of namespace Threads
/**
*/
typedef DH Container;
+ /**
+ * A type for an iterator over the faces of a cell. This is
+ * what the face() function returns.
+ */
+ typedef
+ TriaIterator<DoFAccessor<DH::dimension-1, DH, level_dof_access> >
+ face_iterator;
+
/**
* @name Constructors and initialization
*/
/**
* Return an iterator to the @p ith face of this cell.
*
- * This function is not implemented in 1D, and maps to
- * DoFAccessor::line in 2D.
+ * This function is not implemented in 1D, and returns
+ * DoFAccessor::line in 2D and DoFAccessor::quad in 3d.
*/
- TriaIterator<DoFAccessor<DH::dimension-1,DH, level_dof_access> >
+ face_iterator
face (const unsigned int i) const;
/**
};
-template <int sd, class DH, bool lda>
+template <int sd, class DH, bool level_dof_access>
inline
bool
-DoFAccessor<sd, DH, lda>::is_level_cell()
+DoFAccessor<sd, DH, level_dof_access>::is_level_cell()
{
- return lda;
+ return level_dof_access;
}
/*------------------------- Functions: DoFAccessor ---------------------------*/
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor ()
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor ()
{
Assert (false, ExcInvalidObject());
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (
const Triangulation<DH::dimension,DH::space_dimension> *tria,
const int level,
const int index,
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
template <int structdim2, int dim2, int spacedim2>
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
{
Assert (false, ExcInvalidObject());
}
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<dim2, DH2, lda2> &other)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const DoFAccessor<dim2, DH2, level_dof_access2> &other)
: BaseClass(other),
dof_handler(0)
{
-template <int structdim, class DH, bool lda>
-template <bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <bool level_dof_access2>
inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<structdim, DH, lda2> &other)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const DoFAccessor<structdim, DH, level_dof_access2> &other)
: BaseClass(other),
dof_handler(const_cast<DH *>(other.dof_handler))
{
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim,DH,lda>::set_dof_handler (DH *dh)
+DoFAccessor<structdim,DH,level_dof_access>::set_dof_handler (DH *dh)
{
Assert (dh != 0, ExcInvalidObject());
this->dof_handler = dh;
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
const DH &
-DoFAccessor<structdim,DH,lda>::get_dof_handler () const
+DoFAccessor<structdim,DH,level_dof_access>::get_dof_handler () const
{
return *this->dof_handler;
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim,DH,lda>::copy_from (
+DoFAccessor<structdim,DH,level_dof_access>::copy_from (
const TriaAccessorBase<structdim, DH::dimension, DH::space_dimension> &da)
{
Assert (this->dof_handler != 0, ExcInvalidObject());
-template <int structdim, class DH, bool lda>
-template <bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <bool level_dof_access2>
inline
void
-DoFAccessor<structdim,DH,lda>::copy_from (const DoFAccessor<structdim,DH,lda2> &a)
+DoFAccessor<structdim,DH,level_dof_access>::copy_from (const DoFAccessor<structdim,DH,level_dof_access2> &a)
{
BaseClass::copy_from (a);
set_dof_handler (a.dof_handler);
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
bool
-DoFAccessor<structdim,DH,lda>::operator == (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<structdim,DH,level_dof_access>::operator == (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
{
Assert (structdim == dim2, ExcCantCompareIterators());
Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
bool
-DoFAccessor<structdim,DH,lda>::operator != (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<structdim,DH,level_dof_access>::operator != (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
{
Assert (structdim == dim2, ExcCantCompareIterators());
Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-TriaIterator<DoFAccessor<structdim,DH,lda> >
-DoFAccessor<structdim,DH,lda>::child (const unsigned int i) const
+TriaIterator<DoFAccessor<structdim,DH,level_dof_access> >
+DoFAccessor<structdim,DH,level_dof_access>::child (const unsigned int i) const
{
Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
ExcMessage ("DoFHandler not initialized"));
TriaIterator<TriaAccessor<structdim,DH::dimension,DH::space_dimension> >
t = TriaAccessor<structdim,DH::dimension,DH::space_dimension>::child(i);
- TriaIterator<DoFAccessor<structdim,DH,lda> > q (*t, this->dof_handler);
+ TriaIterator<DoFAccessor<structdim,DH,level_dof_access> > q (*t, this->dof_handler);
return q;
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-TriaIterator<DoFAccessor<structdim,DH,lda> >
-DoFAccessor<structdim,DH,lda>::parent () const
+TriaIterator<DoFAccessor<structdim,DH,level_dof_access> >
+DoFAccessor<structdim,DH,level_dof_access>::parent () const
{
Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
ExcMessage ("DoFHandler not initialized"));
else
previous_level = 0;
- TriaIterator<DoFAccessor<structdim,DH,lda> > q (this->tria,
+ TriaIterator<DoFAccessor<structdim,DH,level_dof_access> > q (this->tria,
previous_level,
this->parent_index (),
this->dof_handler);
}
}
- template<class DH, bool lda>
+ template<class DH, bool level_dof_access>
static
- void set_mg_dof_indices (const dealii::DoFAccessor<1,DH,lda> &,
+ void set_mg_dof_indices (const dealii::DoFAccessor<1,DH,level_dof_access> &,
const int,
const std::vector<types::global_dof_index> &,
const unsigned int)
- template<class DH, bool lda>
+ template<class DH, bool level_dof_access>
static
- void set_mg_dof_indices (dealii::DoFAccessor<2, DH,lda> &accessor,
+ void set_mg_dof_indices (dealii::DoFAccessor<2, DH,level_dof_access> &accessor,
const int level,
const std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
- template<class DH, bool lda>
+ template<class DH, bool level_dof_access>
static
- void set_mg_dof_indices (const dealii::DoFAccessor<3, DH,lda> &,
+ void set_mg_dof_indices (const dealii::DoFAccessor<3, DH,level_dof_access> &,
const int,
const std::vector<types::global_dof_index> &,
const unsigned int)
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
types::global_dof_index
-DoFAccessor<dim,DH,lda>::dof_index (const unsigned int i,
+DoFAccessor<dim,DH,level_dof_access>::dof_index (const unsigned int i,
const unsigned int fe_index) const
{
// access the respective DoF
}
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
types::global_dof_index
-DoFAccessor<structdim, DH,lda>::mg_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::mg_dof_index (const int level,
const unsigned int i) const
{
return this->dof_handler->template get_dof_index<structdim> (level, this->present_index, 0, i);
}
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<dim,DH,lda>::set_dof_index (const unsigned int i,
+DoFAccessor<dim,DH,level_dof_access>::set_dof_index (const unsigned int i,
const types::global_dof_index index,
const unsigned int fe_index) const
{
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
unsigned int
-DoFAccessor<dim,DH,lda>::n_active_fe_indices () const
+DoFAccessor<dim,DH,level_dof_access>::n_active_fe_indices () const
{
// access the respective DoF
return
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
unsigned int
-DoFAccessor<dim,DH,lda>::nth_active_fe_index (const unsigned int n) const
+DoFAccessor<dim,DH,level_dof_access>::nth_active_fe_index (const unsigned int n) const
{
// access the respective DoF
return
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
bool
-DoFAccessor<dim,DH,lda>::fe_index_is_active (const unsigned int fe_index) const
+DoFAccessor<dim,DH,level_dof_access>::fe_index_is_active (const unsigned int fe_index) const
{
// access the respective DoF
return
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
types::global_dof_index
-DoFAccessor<structdim, DH,lda>::vertex_dof_index (const unsigned int vertex,
+DoFAccessor<structdim, DH,level_dof_access>::vertex_dof_index (const unsigned int vertex,
const unsigned int i,
const unsigned int fe_index) const
{
}
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
types::global_dof_index
-DoFAccessor<structdim, DH,lda>::mg_vertex_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::mg_vertex_dof_index (const int level,
const unsigned int vertex,
const unsigned int i,
const unsigned int fe_index) const
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim, DH,lda>::set_vertex_dof_index (const unsigned int vertex,
+DoFAccessor<structdim, DH,level_dof_access>::set_vertex_dof_index (const unsigned int vertex,
const unsigned int i,
const types::global_dof_index index,
const unsigned int fe_index) const
}
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim, DH,lda>::set_mg_vertex_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::set_mg_vertex_dof_index (const int level,
const unsigned int vertex,
const unsigned int i,
const types::global_dof_index index,
}
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim, DH,lda>::set_mg_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_index (const int level,
const unsigned int i,
const types::global_dof_index index) const
{
}
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
inline
const FiniteElement<DH::dimension,DH::space_dimension> &
-DoFAccessor<dim,DH,lda>::get_fe (const unsigned int fe_index) const
+DoFAccessor<dim,DH,level_dof_access>::get_fe (const unsigned int fe_index) const
{
Assert (fe_index_is_active (fe_index) == true,
ExcMessage ("This function can only be called for active fe indices"));
{
namespace DoFAccessor
{
- template <class DH, bool lda>
- void get_dof_indices (const dealii::DoFAccessor<1,DH,lda> &accessor,
+ template <class DH, bool level_dof_access>
+ void get_dof_indices (const dealii::DoFAccessor<1,DH,level_dof_access> &accessor,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
{
- template <class DH, bool lda>
- void get_dof_indices (const dealii::DoFAccessor<2,DH,lda> &accessor,
+ template <class DH, bool level_dof_access>
+ void get_dof_indices (const dealii::DoFAccessor<2,DH,level_dof_access> &accessor,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
{
- template <class DH, bool lda>
- void get_dof_indices (const dealii::DoFAccessor<3,DH,lda> &accessor,
+ template <class DH, bool level_dof_access>
+ void get_dof_indices (const dealii::DoFAccessor<3,DH,level_dof_access> &accessor,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
{
- template<class DH, bool lda>
- void get_mg_dof_indices (const dealii::DoFAccessor<1, DH,lda> &accessor,
+ template<class DH, bool level_dof_access>
+ void get_mg_dof_indices (const dealii::DoFAccessor<1, DH,level_dof_access> &accessor,
const int level,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
- template<class DH, bool lda>
- void get_mg_dof_indices (const dealii::DoFAccessor<2, DH,lda> &accessor,
+ template<class DH, bool level_dof_access>
+ void get_mg_dof_indices (const dealii::DoFAccessor<2, DH,level_dof_access> &accessor,
const int level,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
- template<class DH, bool lda>
- void get_mg_dof_indices (const dealii::DoFAccessor<3, DH,lda> &accessor,
+ template<class DH, bool level_dof_access>
+ void get_mg_dof_indices (const dealii::DoFAccessor<3, DH,level_dof_access> &accessor,
const int level,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
void
-DoFAccessor<structdim,DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices,
+DoFAccessor<structdim,DH,level_dof_access>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index) const
{
Assert (this->dof_handler != 0, ExcNotInitialized());
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
-void DoFAccessor<structdim, DH,lda>::get_mg_dof_indices (const int level,
+void DoFAccessor<structdim, DH,level_dof_access>::get_mg_dof_indices (const int level,
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index) const
{
}
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
inline
-void DoFAccessor<structdim, DH,lda>::set_mg_dof_indices (const int level,
+void DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_indices (const int level,
const std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index)
{
{
namespace DoFAccessor
{
- template <bool lda, class DH>
+ template <bool level_dof_access, class DH>
inline
- typename dealii::internal::DoFHandler::Iterators<DH, lda>::quad_iterator
+ typename dealii::internal::DoFHandler::Iterators<DH, level_dof_access>::quad_iterator
get_quad(const dealii::Triangulation<DH::dimension, DH::space_dimension> *tria,
unsigned int index,
DH *dof_handler)
}
- template<bool lda>
+ template<bool level_dof_access>
inline
- typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, lda>::quad_iterator
+ typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, level_dof_access>::quad_iterator
get_quad(const dealii::Triangulation<2,2> *,
unsigned int,
dealii::DoFHandler<2,2> *)
{
Assert(false, ExcNotImplemented());
- return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, lda>::line_iterator();
+ return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, level_dof_access>::line_iterator();
}
- template<bool lda>
+ template<bool level_dof_access>
inline
- typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, lda>::quad_iterator
+ typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, level_dof_access>::quad_iterator
get_quad(const dealii::Triangulation<2,3> *,
unsigned int,
dealii::DoFHandler<2,3> *)
{
Assert(false, ExcNotImplemented());
- return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, lda>::line_iterator();
+ return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, level_dof_access>::line_iterator();
}
- template<bool lda>
+ template<bool level_dof_access>
inline
- typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, lda>::quad_iterator
+ typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, level_dof_access>::quad_iterator
get_quad(const dealii::Triangulation<2,2> *,
unsigned int,
dealii::hp::DoFHandler<2,2> *)
{
Assert(false, ExcNotImplemented());
- return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, lda>::line_iterator();
+ return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, level_dof_access>::line_iterator();
}
- template<bool lda>
+ template<bool level_dof_access>
inline
- typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, lda>::quad_iterator
+ typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, level_dof_access>::quad_iterator
get_quad(const dealii::Triangulation<2,3> *,
unsigned int,
dealii::hp::DoFHandler<2,3> *)
{
Assert(false, ExcNotImplemented());
- return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, lda>::line_iterator();
+ return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, level_dof_access>::line_iterator();
}
}
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-typename dealii::internal::DoFHandler::Iterators<DH,lda>::line_iterator
-DoFAccessor<structdim,DH,lda>::line (const unsigned int i) const
+typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::line_iterator
+DoFAccessor<structdim,DH,level_dof_access>::line (const unsigned int i) const
{
// if we are asking for a particular line and this object refers to
// a line, then the only valid index is i==0 and we should return
Assert (i==0, ExcMessage ("You can only ask for line zero if the "
"current object is a line itself."));
return
- typename dealii::internal::DoFHandler::Iterators<DH,lda>::cell_iterator
+ typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::cell_iterator
(&this->get_triangulation(),
this->level(),
this->index(),
Assert (DH::dimension > 1, ExcImpossibleInDim(DH::dimension));
// checking of 'i' happens in line_index(i)
- return typename dealii::internal::DoFHandler::Iterators<DH,lda>::line_iterator
+ return typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::line_iterator
(this->tria,
0, // only sub-objects are allowed, which have no level
this->line_index(i),
}
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
inline
-typename dealii::internal::DoFHandler::Iterators<DH,lda>::quad_iterator
-DoFAccessor<structdim,DH,lda>::quad (const unsigned int i) const
+typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::quad_iterator
+DoFAccessor<structdim,DH,level_dof_access>::quad (const unsigned int i) const
{
// if we are asking for a
// particular quad and this object
Assert (DH::dimension > 2, ExcImpossibleInDim(DH::dimension));
// checking of 'i' happens in quad_index(i)
- return typename dealii::internal::DoFHandler::Iterators<DH,lda>::quad_iterator
+ return typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::quad_iterator
(this->tria,
0, // only sub-objects are allowed, which have no level
this->quad_index(i),
/*------------------------- Functions: DoFAccessor<0,1,spacedim> ---------------------------*/
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor ()
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor ()
{
Assert (false, ExcInvalidObject());
}
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
DoFAccessor (const Triangulation<1,spacedim> *tria,
const typename TriaAccessor<0,1,spacedim>::VertexKind vertex_kind,
const unsigned int vertex_index,
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
DoFAccessor (const Triangulation<1,spacedim> *,
const int ,
const int ,
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
template <int structdim2, int dim2, int spacedim2>
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
{
Assert (false, ExcInvalidObject());
}
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor (const DoFAccessor<dim2, DH2, lda2> &)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor (const DoFAccessor<dim2, DH2, level_dof_access2> &)
{
Assert (false, ExcInvalidObject());
}
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
void
-DoFAccessor<0,DH<1,spacedim>, lda>::set_dof_handler (DH<1,spacedim> *dh)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::set_dof_handler (DH<1,spacedim> *dh)
{
Assert (dh != 0, ExcInvalidObject());
this->dof_handler = dh;
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
const DH<1,spacedim> &
-DoFAccessor<0,DH<1,spacedim>, lda>::get_dof_handler () const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::get_dof_handler () const
{
return *this->dof_handler;
}
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
void
-DoFAccessor<0,DH<1,spacedim>, lda>::get_dof_indices (
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::get_dof_indices (
std::vector<types::global_dof_index> &dof_indices,
const unsigned int fe_index) const
{
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
types::global_dof_index
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
vertex_dof_index (const unsigned int vertex,
const unsigned int i,
const unsigned int fe_index) const
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
inline
void
-DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const TriaAccessorBase<0,1,spacedim> &da)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::copy_from (const TriaAccessorBase<0,1,spacedim> &da)
{
Assert (this->dof_handler != 0, ExcInvalidObject());
BaseClass::copy_from(da);
-template <template <int, int> class DH, int spacedim, bool lda>
-template <bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <bool level_dof_access2>
inline
void
-DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const DoFAccessor<0,DH<1,spacedim>, lda2> &a)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::copy_from (const DoFAccessor<0,DH<1,spacedim>, level_dof_access2> &a)
{
BaseClass::copy_from (a);
set_dof_handler (a.dof_handler);
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
bool
-DoFAccessor<0,DH<1,spacedim>, lda>::operator == (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::operator == (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
{
Assert (dim2 == 0, ExcCantCompareIterators());
Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
bool
-DoFAccessor<0,DH<1,spacedim>, lda>::operator != (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::operator != (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
{
Assert (dim2 == 0, ExcCantCompareIterators());
Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
* implemented for hp::DoFHandler
* objects.
*/
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<1,spacedim>, lda> &accessor)
+ update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<1,spacedim>, level_dof_access> &accessor)
{
// check as in documentation that
// cell is either active, or dofs
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<2,spacedim>, lda> &accessor)
+ update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<2,spacedim>, level_dof_access> &accessor)
{
// check as in documentation that
// cell is either active, or dofs
}
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<3,spacedim>, lda> &accessor)
+ update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<3,spacedim>, level_dof_access> &accessor)
{
// check as in documentation that
// cell is either active, or dofs
// hp::DoFHandler objects. it's
// not implemented there, for no
// space dimension
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
void
- update_cell_dof_indices_cache (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor)
+ update_cell_dof_indices_cache (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor)
{
// caches are only for cells with DoFs, i.e., for active ones
if (accessor.has_children())
ExcInternalError());
std::vector<types::global_dof_index> dof_indices (dofs_per_cell);
- static_cast<const dealii::DoFAccessor<dim,dealii::hp::DoFHandler<dim,spacedim>,lda> &>
+ static_cast<const dealii::DoFAccessor<dim,dealii::hp::DoFHandler<dim,spacedim>,level_dof_access> &>
(accessor).get_dof_indices (dof_indices, accessor.active_fe_index());
types::global_dof_index *next_dof_index
* implemented for
* hp::DoFHandler objects.
*/
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- set_dof_indices (DoFCellAccessor<DoFHandler<1,spacedim>, lda> &accessor,
+ set_dof_indices (DoFCellAccessor<DoFHandler<1,spacedim>, level_dof_access> &accessor,
const std::vector<types::global_dof_index> &local_dof_indices)
{
Assert (accessor.has_children() == false,
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- set_dof_indices (DoFCellAccessor<DoFHandler<2,spacedim>, lda> &accessor,
+ set_dof_indices (DoFCellAccessor<DoFHandler<2,spacedim>, level_dof_access> &accessor,
const std::vector<types::global_dof_index> &local_dof_indices)
{
Assert (accessor.has_children() == false,
- template <int spacedim, bool lda>
+ template <int spacedim, bool level_dof_access>
static
void
- set_dof_indices (DoFCellAccessor<DoFHandler<3,spacedim>, lda> &accessor,
+ set_dof_indices (DoFCellAccessor<DoFHandler<3,spacedim>, level_dof_access> &accessor,
const std::vector<types::global_dof_index> &local_dof_indices)
{
Assert (accessor.has_children() == false,
// hp::DoFHandler objects. it's
// not implemented there, for no
// space dimension
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
void
- set_dof_indices (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &,
+ set_dof_indices (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &,
const std::vector<types::global_dof_index> &)
{
Assert (false, ExcNotImplemented());
* function in the parent class
* is supposed to do.
*/
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
unsigned int
- active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, lda> &)
+ active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, level_dof_access> &)
{
// ::DoFHandler only supports a
// single active fe with index
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
unsigned int
- active_fe_index (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor)
+ active_fe_index (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor)
{
Assert (static_cast<unsigned int>(accessor.level()) < accessor.dof_handler->levels.size(),
ExcMessage ("DoFHandler not initialized"));
* in the parent class is
* supposed to do.
*/
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
void
- set_active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, lda> &,
+ set_active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, level_dof_access> &,
const unsigned int i)
{
// ::DoFHandler only supports a
// single active fe with index
// zero
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (i == 0, typename BaseClass::ExcInvalidObject());
}
- template <int dim, int spacedim, bool lda>
+ template <int dim, int spacedim, bool level_dof_access>
static
void
- set_active_fe_index (DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+ set_active_fe_index (DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const unsigned int i)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (static_cast<unsigned int>(accessor.level()) <
- template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+ template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
OutputVector &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+ template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
OutputVector &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+ template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const ConstraintMatrix &constraints,
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
OutputVector &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+ template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const ConstraintMatrix &constraints,
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
OutputVector &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename number, class OutputMatrix>
+ template <int dim, int spacedim, bool level_dof_access, typename number, class OutputMatrix>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const dealii::FullMatrix<number> &local_source,
OutputMatrix &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename number, class OutputMatrix>
+ template <int dim, int spacedim, bool level_dof_access, typename number, class OutputMatrix>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const dealii::FullMatrix<number> &local_source,
OutputMatrix &global_destination)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename number,
+ template <int dim, int spacedim, bool level_dof_access, typename number,
class OutputMatrix, typename OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const dealii::FullMatrix<number> &local_matrix,
const dealii::Vector<number> &local_vector,
OutputMatrix &global_matrix,
OutputVector &global_vector)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
- template <int dim, int spacedim, bool lda, typename number,
+ template <int dim, int spacedim, bool level_dof_access, typename number,
class OutputMatrix, typename OutputVector>
static
void
- distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+ distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
const dealii::FullMatrix<number> &local_matrix,
const dealii::Vector<number> &local_vector,
OutputMatrix &global_matrix,
OutputVector &global_vector)
{
- typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+ typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
Assert (accessor.dof_handler != 0,
typename BaseClass::ExcInvalidObject());
Assert (&accessor.get_fe() != 0,
}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (
const Triangulation<DH::dimension,DH::space_dimension> *tria,
const int level,
const int index,
const AccessorData *local_data)
:
- DoFAccessor<DH::dimension,DH,lda> (tria,level,index, local_data)
+ DoFAccessor<DH::dimension,DH,level_dof_access> (tria,level,index, local_data)
{}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <int structdim2, int dim2, int spacedim2>
inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
{
Assert (false, typename BaseClass::ExcInvalidObject());
}
-template <class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (const DoFAccessor<dim2,DH2,lda2> &other)
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (const DoFAccessor<dim2,DH2,level_dof_access2> &other)
:
BaseClass(other)
{}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::neighbor (const unsigned int i) const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::neighbor (const unsigned int i) const
{
- TriaIterator<DoFCellAccessor<DH,lda> >
+ TriaIterator<DoFCellAccessor<DH,level_dof_access> >
q (this->tria,
this->neighbor_level (i),
this->neighbor_index (i),
}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::child (const unsigned int i) const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::child (const unsigned int i) const
{
- TriaIterator<DoFCellAccessor<DH,lda> >
+ TriaIterator<DoFCellAccessor<DH,level_dof_access> >
q (this->tria,
this->level()+1,
this->child_index (i),
}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::parent () const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::parent () const
{
- TriaIterator<DoFCellAccessor<DH,lda> >
+ TriaIterator<DoFCellAccessor<DH,level_dof_access> >
q (this->tria,
this->level() - 1,
this->parent_index (),
{
namespace DoFCellAccessor
{
- template <class DH, bool lda>
+ template <class DH, bool level_dof_access>
inline
- TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
- get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+ TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+ get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
const unsigned int i,
const dealii::internal::int2type<1>)
{
- dealii::DoFAccessor<0, DH,lda>
+ dealii::DoFAccessor<0, DH,level_dof_access>
a (&cell.get_triangulation(),
((i == 0) && cell.at_boundary(0)
?
dealii::TriaAccessor<0, 1, DH::space_dimension>::interior_vertex)),
cell.vertex_index(i),
&cell.get_dof_handler());
- return dealii::TriaIterator<dealii::DoFAccessor<0,DH,lda> > (a);
+ return dealii::TriaIterator<dealii::DoFAccessor<0,DH,level_dof_access> > (a);
}
- template <class DH, bool lda>
+ template <class DH, bool level_dof_access>
inline
- TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
- get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+ TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+ get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
const unsigned int i,
const dealii::internal::int2type<2>)
{
}
- template <class DH, bool lda>
+ template <class DH, bool level_dof_access>
inline
- TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
- get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+ TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+ get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
const unsigned int i,
const dealii::internal::int2type<3>)
{
}
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
-TriaIterator<DoFAccessor<DH::dimension-1,DH,lda> >
-DoFCellAccessor<DH,lda>::face (const unsigned int i) const
+typename DoFCellAccessor<DH,level_dof_access>::face_iterator
+DoFCellAccessor<DH,level_dof_access>::face (const unsigned int i) const
{
Assert (i<GeometryInfo<dim>::faces_per_cell, ExcIndexRange (i, 0, GeometryInfo<dim>::faces_per_cell));
Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
void
-DoFCellAccessor<DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+DoFCellAccessor<DH,level_dof_access>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
{
Assert (this->active(), ExcMessage ("get_dof_indices() only works on active cells."));
Assert (this->is_artificial() == false,
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
inline
-void DoFCellAccessor<DH,lda>::get_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+void DoFCellAccessor<DH,level_dof_access>::get_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
{
- DoFAccessor<dim, DH,lda>::get_mg_dof_indices (this->level (), dof_indices);
+ DoFAccessor<dim, DH,level_dof_access>::get_mg_dof_indices (this->level (), dof_indices);
}
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
inline
-void DoFCellAccessor<DH,lda>::set_mg_dof_indices (const std::vector<types::global_dof_index> &dof_indices)
+void DoFCellAccessor<DH,level_dof_access>::set_mg_dof_indices (const std::vector<types::global_dof_index> &dof_indices)
{
- DoFAccessor<dim, DH,lda>::set_mg_dof_indices (this->level (), dof_indices);
+ DoFAccessor<dim, DH,level_dof_access>::set_mg_dof_indices (this->level (), dof_indices);
}
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
inline
-void DoFCellAccessor<DH,lda>::get_active_or_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+void DoFCellAccessor<DH,level_dof_access>::get_active_or_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
{
- if (lda)
+ if (level_dof_access)
get_mg_dof_indices (dof_indices);
else
get_dof_indices (dof_indices);
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <class InputVector, typename number>
inline
void
-DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
Vector<number> &local_values) const
{
get_dof_values (values, local_values.begin(), local_values.end());
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <class InputVector, typename ForwardIterator>
inline
void
-DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
ForwardIterator local_values_begin,
ForwardIterator local_values_end) const
{
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <class InputVector, typename ForwardIterator>
inline
void
-DoFCellAccessor<DH,lda>::get_dof_values (const ConstraintMatrix &constraints,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const ConstraintMatrix &constraints,
const InputVector &values,
ForwardIterator local_values_begin,
ForwardIterator local_values_end) const
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <class OutputVector, typename number>
inline
void
-DoFCellAccessor<DH,lda>::set_dof_values (const Vector<number> &local_values,
+DoFCellAccessor<DH,level_dof_access>::set_dof_values (const Vector<number> &local_values,
OutputVector &values) const
{
Assert (this->is_artificial() == false,
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
const FiniteElement<DH::dimension,DH::space_dimension> &
-DoFCellAccessor<DH,lda>::get_fe () const
+DoFCellAccessor<DH,level_dof_access>::get_fe () const
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
(this->dof_handler) != 0)
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
unsigned int
-DoFCellAccessor<DH,lda>::active_fe_index () const
+DoFCellAccessor<DH,level_dof_access>::active_fe_index () const
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
(this->dof_handler) != 0)
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
inline
void
-DoFCellAccessor<DH,lda>::set_active_fe_index (const unsigned int i)
+DoFCellAccessor<DH,level_dof_access>::set_active_fe_index (const unsigned int i)
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
(this->dof_handler) != 0)
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <typename number, typename OutputVector>
inline
void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
const Vector<number> &local_source,
OutputVector &global_destination) const
{
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <typename ForwardIterator, typename OutputVector>
inline
void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
OutputVector &global_destination) const
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <typename ForwardIterator, typename OutputVector>
inline
void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
const ConstraintMatrix &constraints,
ForwardIterator local_source_begin,
ForwardIterator local_source_end,
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <typename number, typename OutputMatrix>
inline
void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
const FullMatrix<number> &local_source,
OutputMatrix &global_destination) const
{
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
template <typename number, typename OutputMatrix, typename OutputVector>
inline
void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
const FullMatrix<number> &local_matrix,
const Vector<number> &local_vector,
OutputMatrix &global_matrix,
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1999 - 2013 by the deal.II authors
+// Copyright (C) 1999 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
template <int dim>
void
parallelogram (Triangulation<dim> &tria,
- const Point<dim> corners[dim],
+ const Point<dim> (&corners)[dim],
const bool colorize=false);
/**
* @param r The inner radius of the
* torus.
*/
-
void torus (Triangulation<2,3> &tria,
const double R,
const double r);
/**
* Transform the vertices of the given
* triangulation by applying the
- * function object provided as first argument to all its vertices. Since
- * the internal consistency of a
- * triangulation can only be guaranteed
- * if the transformation is applied to
- * the vertices of only one level of
- * hierarchically refined cells, this
- * function may only be used if all cells
- * of the triangulation are on the same
- * refinement level.
+ * function object provided as first argument to all its vertices.
*
* The transformation given as
* argument is used to transform
* return value have to be of
* type <tt>Point<spacedim></tt>.
*
+ * Note: if you are using a parallel::distributed::Triangulation you will have
+ * hanging nodes in your local Triangulation even if your "global" mesh has
+ * no hanging nodes. This will cause issues with wrong positioning of hanging
+ * nodes in ghost cells. The active cells will be correct, but keep in mind that
+ * computations like KellyErrorEstimator will give wrong answers. A safe bet is
+ * to use this function prior to any refinement in parallel.
+ *
* This function is used in the
* "Possibilities for extensions" section
* of step-38. It is also used in step-49.
fix_up_distorted_child_cells (const typename Triangulation<dim,spacedim>::DistortedCellList &distorted_cells,
Triangulation<dim,spacedim> &triangulation);
+#ifdef _MSC_VER
+ // Microsoft's VC++ has a bug where it doesn't want to recognize that
+ // an implementation (definition) of the extract_boundary_mesh function
+ // matches a declaration. This can apparently only be avoided by
+ // doing some contortion with the return type using the following
+ // intermediate type. This is only used when using MS VC++ and uses
+ // the direct way of doing it otherwise
+ template <template <int,int> class Container, int dim, int spacedim>
+ struct ExtractBoundaryMesh
+ {
+ typedef
+ std::map<typename Container<dim-1,spacedim>::cell_iterator,
+ typename Container<dim,spacedim>::face_iterator>
+ return_type;
+ };
+#endif
+
/**
* This function implements a boundary
* subgrid extraction. Given a
* curved boundaries.
*/
template <template <int,int> class Container, int dim, int spacedim>
+#ifndef _MSC_VER
std::map<typename Container<dim-1,spacedim>::cell_iterator,
typename Container<dim,spacedim>::face_iterator>
+#else
+ typename ExtractBoundaryMesh<Container,dim,spacedim>::return_type
+#endif
extract_boundary_mesh (const Container<dim,spacedim> &volume_mesh,
Container<dim-1,spacedim> &surface_mesh,
const std::set<types::boundary_id> &boundary_ids
void transform (const Predicate &predicate,
Triangulation<dim, spacedim> &triangulation)
{
- // ensure that all the cells of the
- // triangulation are on the same level
- Assert (triangulation.n_levels() ==
- static_cast<unsigned int>(triangulation.begin_active()->level()+1),
- ExcMessage ("Not all cells of this triangulation are at the same "
- "refinement level, as is required for this function."));
-
std::vector<bool> treated_vertices (triangulation.n_vertices(),
false);
// and mark it as treated
treated_vertices[cell->vertex_index(v)] = true;
};
+
+
+ // now fix any vertices on hanging nodes so that we don't create any holes
+ if (dim==2)
+ {
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(),
+ endc = triangulation.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children() &&
+ !cell->face(face)->at_boundary())
+ { // this line has children
+ cell->face(face)->child(0)->vertex(1)
+ = (cell->face(face)->vertex(0) +
+ cell->face(face)->vertex(1)) / 2;
+ }
+ }
+ else if (dim==3)
+ {
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(),
+ endc = triangulation.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children() &&
+ !cell->face(face)->at_boundary())
+ { // this face has hanging nodes
+ cell->face(face)->child(0)->vertex(1)
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) / 2.0;
+ cell->face(face)->child(0)->vertex(2)
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) / 2.0;
+ cell->face(face)->child(1)->vertex(3)
+ = (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) / 2.0;
+ cell->face(face)->child(2)->vertex(3)
+ = (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 2.0;
+
+ // center of the face
+ cell->face(face)->child(0)->vertex(3)
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)
+ + cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 4.0;
+ }
+ }
}
}
}
+ /**
+ * The weighted mass matrix for scalar or vector values finite elements.
+ * \f[
+ * \int_Z \omega(x) uv\,dx \quad \text{or} \quad \int_Z \omega(x) \mathbf u\cdot \mathbf v\,dx
+ * \f]
+ *
+ * Likewise, this term can be used on faces, where it computes the integrals
+ * \f[
+ * \int_F \omega(x) uv\,ds \quad \text{or} \quad \int_F \omega(x) \mathbf u\cdot \mathbf v\,ds
+ * \f]
+ *
+ * The size of the vector <tt>weights</tt> must be equal to the
+ * number of quadrature points in the finite element.
+ *
+ * @author Guido Kanschat
+ * @date 2014
+ */
+ template <int dim>
+ void weighted_mass_matrix (
+ FullMatrix<double> &M,
+ const FEValuesBase<dim> &fe,
+ const std::vector<double> weights)
+ {
+ const unsigned int n_dofs = fe.dofs_per_cell;
+ const unsigned int n_components = fe.get_fe().n_components();
+ AssertDimension(M.m(), n_dofs);
+ AssertDimension(M.n(), n_dofs);
+ AssertDimension(weights.size(), fe.n_quadrature_points);
+
+ for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
+ {
+ const double dx = fe.JxW(k) * weights[k];
+
+ for (unsigned int i=0; i<n_dofs; ++i)
+ for (unsigned int j=0; j<n_dofs; ++j)
+ for (unsigned int d=0; d<n_components; ++d)
+ M(i,j) += dx
+ * fe.shape_value_component(j,k,d)
+ * fe.shape_value_component(i,k,d);
+ }
+ }
+
/**
* <i>L<sup>2</sup></i>-inner product for scalar functions.
*
Vector<double> dummy(0);
distribute_local_to_global (local_matrix, dummy, local_dof_indices,
global_matrix, dummy, false,
- internal::bool2type<IsBlockMatrix<MatrixType>::value>());
+ dealii::internal::bool2type<IsBlockMatrix<MatrixType>::value>());
}
typedef unsigned int size_type;
/**
- * Type of matrix entries. In analogy to
- * the STL container classes.
+ * Type of matrix entries. In analogy to the STL container classes.
*/
typedef number value_type;
/**
- * Declare a type that has holds
- * real-valued numbers with the
- * same precision as the template
- * argument to this class. If the
- * template argument of this
- * class is a real data type,
- * then real_type equals the
- * template argument. If the
- * template argument is a
- * std::complex type then
- * real_type equals the type
- * underlying the complex
- * numbers.
+ * Declare a type that has holds real-valued numbers with the same precision
+ * as the template argument to this class. If the template argument of this
+ * class is a real data type, then real_type equals the template
+ * argument. If the template argument is a std::complex type then real_type
+ * equals the type underlying the complex numbers.
*
- * This typedef is used to
- * represent the return type of
- * norms.
+ * This typedef is used to represent the return type of norms.
*/
typedef typename numbers::NumberTraits<number>::real_type real_type;
{
public:
/**
- * Constructor. Since we use
- * accessors only for read
- * access, a const matrix
- * pointer is sufficient.
+ * Constructor. Since we use accessors only for read access, a const
+ * matrix pointer is sufficient.
*/
Accessor (const FullMatrix<number> *matrix,
const size_type row,
const size_type col);
/**
- * Row number of the element
- * represented by this
- * object.
+ * Row number of the element represented by this object.
*/
size_type row() const;
/**
- * Column number of the
- * element represented by
- * this object.
+ * Column number of the element represented by this object.
*/
size_type column() const;
unsigned short a_col;
/*
- * Make enclosing class a
- * friend.
+ * Make enclosing class a friend.
*/
friend class const_iterator;
};
const Accessor *operator-> () const;
/**
- * Comparison. True, if
- * both iterators point to
- * the same matrix
- * position.
+ * Comparison. True, if both iterators point to the same matrix position.
*/
bool operator == (const const_iterator &) const;
/**
bool operator != (const const_iterator &) const;
/**
- * Comparison operator. Result is
- * true if either the first row
- * number is smaller or if the row
- * numbers are equal and the first
- * index is smaller.
+ * Comparison operator. Result is true if either the first row number is
+ * smaller or if the row numbers are equal and the first index is smaller.
*/
bool operator < (const const_iterator &) const;
/**
- * Comparison operator. Compares just
- * the other way around than the
+ * Comparison operator. Compares just the other way around than the
* operator above.
*/
bool operator > (const const_iterator &) const;
private:
/**
- * Store an object of the
- * accessor class.
+ * Store an object of the accessor class.
*/
Accessor accessor;
};
/**
- * @name Constructors and initalization.
- * See also the base class Table.
+ * @name Constructors and initalization. See also the base class Table.
*/
//@{
/**
- * Constructor. Initialize the
- * matrix as a square matrix with
- * dimension <tt>n</tt>.
+ * Constructor. Initialize the matrix as a square matrix with dimension
+ * <tt>n</tt>.
*
- * In order to avoid the implicit
- * conversion of integers and
- * other types to a matrix, this
- * constructor is declared
- * <tt>explicit</tt>.
+ * In order to avoid the implicit conversion of integers and other types to
+ * a matrix, this constructor is declared <tt>explicit</tt>.
*
- * By default, no memory is
- * allocated.
+ * By default, no memory is allocated.
*/
explicit FullMatrix (const size_type n = 0);
/**
- * Constructor. Initialize the
- * matrix as a rectangular
- * matrix.
+ * Constructor. Initialize the matrix as a rectangular matrix.
*/
FullMatrix (const size_type rows,
const size_type cols);
/**
- * Copy constructor. This
- * constructor does a deep copy
- * of the matrix. Therefore, it
- * poses a possible efficiency
- * problem, if for example,
- * function arguments are passed
- * by value rather than by
- * reference. Unfortunately, we
- * can't mark this copy
- * constructor <tt>explicit</tt>,
- * since that prevents the use of
- * this class in containers, such
- * as <tt>std::vector</tt>. The
- * responsibility to check
- * performance of programs must
- * therefore remain with the
- * user of this class.
+ * Copy constructor. This constructor does a deep copy of the
+ * matrix. Therefore, it poses a possible efficiency problem, if for
+ * example, function arguments are passed by value rather than by
+ * reference. Unfortunately, we can't mark this copy constructor
+ * <tt>explicit</tt>, since that prevents the use of this class in
+ * containers, such as <tt>std::vector</tt>. The responsibility to check
+ * performance of programs must therefore remain with the user of this
+ * class.
*/
FullMatrix (const FullMatrix &);
/**
- * Constructor initializing from
- * an array of numbers. The array
- * is arranged line by line. No
- * range checking is performed.
+ * Constructor initializing from an array of numbers. The array is arranged
+ * line by line. No range checking is performed.
*/
FullMatrix (const size_type rows,
const size_type cols,
const number *entries);
/**
- * Construct a full matrix that
- * equals the identity matrix of
- * the size of the
- * argument. Using this
- * constructor, one can easily
- * create an identity matrix of
- * size <code>n</code> by saying
+ * Construct a full matrix that equals the identity matrix of the size of
+ * the argument. Using this constructor, one can easily create an identity
+ * matrix of size <code>n</code> by saying
* @code
* FullMatrix<double> M(IdentityMatrix(n));
* @endcode
operator = (const FullMatrix<number2> &);
/**
- * This operator assigns a scalar
- * to a matrix. To avoid
- * confusion with the semantics
- * of this function, zero is the
- * only value allowed for
- * <tt>d</tt>, allowing you to
- * clear a matrix in an intuitive
- * way.
+ * This operator assigns a scalar to a matrix. To avoid confusion with the
+ * semantics of this function, zero is the only value allowed for
+ * <tt>d</tt>, allowing you to clear a matrix in an intuitive way.
*/
FullMatrix<number> &
operator = (const number d);
/**
- * Copy operator to create a full
- * matrix that equals the
- * identity matrix of the size of
- * the argument. This way, one can easily
- * create an identity matrix of
- * size <code>n</code> by saying
+ * Copy operator to create a full matrix that equals the identity matrix of
+ * the size of the argument. This way, one can easily create an identity
+ * matrix of size <code>n</code> by saying
* @code
* M = IdentityMatrix(n);
* @endcode
operator = (const IdentityMatrix &id);
/**
- * Assignment operator for a
- * LapackFullMatrix. The calling matrix
- * must be of the same size as the
- * LAPACK matrix.
+ * Assignment operator for a LapackFullMatrix. The calling matrix must be of
+ * the same size as the LAPACK matrix.
*/
template <typename number2>
FullMatrix<number> &
/**
- * Assignment from different
- * matrix classes. This
- * assignment operator uses
- * iterators of the class
- * MATRIX. Therefore, sparse
- * matrices are possible sources.
+ * Assignment from different matrix classes. This assignment operator uses
+ * iterators of the class MATRIX. Therefore, sparse matrices are possible
+ * sources.
*/
template <class MATRIX>
void copy_from (const MATRIX &);
/**
- * Transposing assignment from
- * different matrix classes. This
- * assignment operator uses
- * iterators of the class
- * MATRIX. Therefore, sparse
- * matrices are possible sources.
+ * Transposing assignment from different matrix classes. This assignment
+ * operator uses iterators of the class MATRIX. Therefore, sparse matrices
+ * are possible sources.
*/
template <class MATRIX>
void copy_transposed (const MATRIX &);
/**
- * Fill matrix with elements
- * extracted from a tensor,
- * taking rows included between
- * <tt>r_i</tt> and <tt>r_j</tt>
- * and columns between
- * <tt>c_i</tt> and
- * <tt>c_j</tt>. The resulting
- * matrix is then inserted in the
- * destination matrix at position
- * <tt>(dst_r, dst_c)</tt> Checks
- * on the indices are made.
+ * Fill matrix with elements extracted from a tensor, taking rows included
+ * between <tt>r_i</tt> and <tt>r_j</tt> and columns between <tt>c_i</tt>
+ * and <tt>c_j</tt>. The resulting matrix is then inserted in the
+ * destination matrix at position <tt>(dst_r, dst_c)</tt> Checks on the
+ * indices are made.
*/
template <int dim>
void
const size_type dst_c=0);
/**
- * Insert a submatrix (also
- * rectangular) into a tensor,
- * putting its upper left element
- * at the specified position
- * <tt>(dst_r, dst_c)</tt> and
- * the other elements
- * consequently. Default values
- * are chosen so that no
- * parameter needs to be specified
- * if the size of the tensor and
- * that of the matrix coincide.
+ * Insert a submatrix (also rectangular) into a tensor, putting its upper
+ * left element at the specified position <tt>(dst_r, dst_c)</tt> and the
+ * other elements consequently. Default values are chosen so that no
+ * parameter needs to be specified if the size of the tensor and that of the
+ * matrix coincide.
*/
template <int dim>
void
/**
* Fill rectangular block.
*
- * A rectangular block of the
- * matrix <tt>src</tt> is copied into
- * <tt>this</tt>. The upper left
- * corner of the block being
- * copied is
- * <tt>(src_offset_i,src_offset_j)</tt>.
- * The upper left corner of the
- * copied block is
- * <tt>(dst_offset_i,dst_offset_j)</tt>.
- * The size of the rectangular
- * block being copied is the
- * maximum size possible,
- * determined either by the size
- * of <tt>this</tt> or <tt>src</tt>.
+ * A rectangular block of the matrix <tt>src</tt> is copied into
+ * <tt>this</tt>. The upper left corner of the block being copied is
+ * <tt>(src_offset_i,src_offset_j)</tt>. The upper left corner of the
+ * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>. The size of the
+ * rectangular block being copied is the maximum size possible, determined
+ * either by the size of <tt>this</tt> or <tt>src</tt>.
*/
template <typename number2>
void fill (const FullMatrix<number2> &src,
/**
- * Make function of base class
- * available.
+ * Make function of base class available.
*/
template <typename number2>
void fill (const number2 *);
/**
- * Fill with permutation of
- * another matrix.
+ * Fill with permutation of another matrix.
*
- * The matrix <tt>src</tt> is copied
- * into the target. The two
- * permutation <tt>p_r</tt> and
- * <tt>p_c</tt> operate in a way, such
- * that <tt>result(i,j) =
- * src(p_r[i], p_c[j])</tt>.
+ * The matrix <tt>src</tt> is copied into the target. The two permutation
+ * <tt>p_r</tt> and <tt>p_c</tt> operate in a way, such that <tt>result(i,j)
+ * = src(p_r[i], p_c[j])</tt>.
*
- * The vectors may also be a
- * selection from a larger set of
- * integers, if the matrix
- * <tt>src</tt> is bigger. It is also
- * possible to duplicate rows or
+ * The vectors may also be a selection from a larger set of integers, if the
+ * matrix <tt>src</tt> is bigger. It is also possible to duplicate rows or
* columns by this method.
*/
template <typename number2>
*/
/**
- * Comparison operator. Be
- * careful with this thing, it
- * may eat up huge amounts of
- * computing time! It is most
- * commonly used for internal
- * consistency checks of
- * programs.
+ * Comparison operator. Be careful with this thing, it may eat up huge
+ * amounts of computing time! It is most commonly used for internal
+ * consistency checks of programs.
*/
bool operator == (const FullMatrix<number> &) const;
/**
- * Number of rows of this matrix.
- * To remember: this matrix is an
- * <i>m x n</i>-matrix.
+ * Number of rows of this matrix. To remember: this matrix is an <i>m x
+ * n</i>-matrix.
*/
size_type m () const;
/**
- * Number of columns of this matrix.
- * To remember: this matrix is an
- * <i>m x n</i>-matrix.
+ * Number of columns of this matrix. To remember: this matrix is an <i>m x
+ * n</i>-matrix.
*/
size_type n () const;
/**
- * Return whether the matrix
- * contains only elements with
- * value zero. This function is
- * mainly for internal
- * consistency checks and should
- * seldom be used when not in
- * debug mode since it uses quite
- * some time.
+ * Return whether the matrix contains only elements with value zero. This
+ * function is mainly for internal consistency checks and should seldom be
+ * used when not in debug mode since it uses quite some time.
*/
bool all_zero () const;
/**
- * Return the square of the norm
- * of the vector <tt>v</tt> induced by
- * this matrix,
- * i.e. <i>(v,Mv)</i>. This is
- * useful, e.g. in the finite
- * element context, where the
- * <i>L<sup>2</sup></i> norm of a
- * function equals the matrix
- * norm with respect to the mass
- * matrix of the vector
- * representing the nodal values
- * of the finite element
- * function.
- *
- * Obviously, the matrix needs to be
- * quadratic for this operation, and for
- * the result to actually be a norm it
- * also needs to be either real symmetric
- * or complex hermitian.
- *
- * The underlying template types of both
- * this matrix and the given vector
- * should either both be real or
- * complex-valued, but not mixed, for
- * this function to make sense.
+ * Return the square of the norm of the vector <tt>v</tt> induced by this
+ * matrix, i.e. <i>(v,Mv)</i>. This is useful, e.g. in the finite element
+ * context, where the <i>L<sup>2</sup></i> norm of a function equals the
+ * matrix norm with respect to the mass matrix of the vector representing
+ * the nodal values of the finite element function.
+ *
+ * Obviously, the matrix needs to be quadratic for this operation, and for
+ * the result to actually be a norm it also needs to be either real
+ * symmetric or complex hermitian.
+ *
+ * The underlying template types of both this matrix and the given vector
+ * should either both be real or complex-valued, but not mixed, for this
+ * function to make sense.
*/
template <typename number2>
number2 matrix_norm_square (const Vector<number2> &v) const;
/**
- * Build the matrix scalar
- * product <tt>u<sup>T</sup> M
- * v</tt>. This function is
- * mostly useful when building
- * the cellwise scalar product of
- * two functions in the finite
- * element context.
+ * Build the matrix scalar product <tt>u<sup>T</sup> M v</tt>. This function
+ * is mostly useful when building the cellwise scalar product of two
+ * functions in the finite element context.
*
- * The underlying template types of both
- * this matrix and the given vector
- * should either both be real or
- * complex-valued, but not mixed, for
- * this function to make sense.
+ * The underlying template types of both this matrix and the given vector
+ * should either both be real or complex-valued, but not mixed, for this
+ * function to make sense.
*/
template <typename number2>
number2 matrix_scalar_product (const Vector<number2> &u,
const Vector<number2> &v) const;
/**
- * Return the
- * <i>l<sub>1</sub></i>-norm of
- * the matrix, where
- * $||M||_1 = \max_j \sum_i
- * |M_{ij}|$ (maximum of
- * the sums over columns).
+ * Return the <i>l<sub>1</sub></i>-norm of the matrix, where $||M||_1 =
+ * \max_j \sum_i |M_{ij}|$ (maximum of the sums over columns).
*/
real_type l1_norm () const;
/**
- * Return the $l_\infty$-norm of
- * the matrix, where
- * $||M||_\infty = \max_i \sum_j
- * |M_{ij}|$ (maximum of the sums
- * over rows).
+ * Return the $l_\infty$-norm of the matrix, where $||M||_\infty = \max_i
+ * \sum_j |M_{ij}|$ (maximum of the sums over rows).
*/
real_type linfty_norm () const;
/**
- * Compute the Frobenius norm of
- * the matrix. Return value is
- * the root of the square sum of
- * all matrix entries.
+ * Compute the Frobenius norm of the matrix. Return value is the root of
+ * the square sum of all matrix entries.
*
- * @note For the timid among us:
- * this norm is not the norm
- * compatible with the
- * <i>l<sub>2</sub></i>-norm of
- * the vector space.
+ * @note For the timid among us: this norm is not the norm compatible with
+ * the <i>l<sub>2</sub></i>-norm of the vector space.
*/
real_type frobenius_norm () const;
/**
- * Compute the relative norm of
- * the skew-symmetric part. The
- * return value is the Frobenius
- * norm of the skew-symmetric
- * part of the matrix divided by
+ * Compute the relative norm of the skew-symmetric part. The return value is
+ * the Frobenius norm of the skew-symmetric part of the matrix divided by
* that of the matrix.
*
- * Main purpose of this function
- * is to check, if a matrix is
- * symmetric within a certain
- * accuracy, or not.
+ * Main purpose of this function is to check, if a matrix is symmetric
+ * within a certain accuracy, or not.
*/
real_type relative_symmetry_norm2 () const;
/**
- * Computes the determinant of a
- * matrix. This is only
- * implemented for one, two, and
- * three dimensions, since for
- * higher dimensions the
- * numerical work explodes.
- * Obviously, the matrix needs to
- * be quadratic for this function.
+ * Computes the determinant of a matrix. This is only implemented for one,
+ * two, and three dimensions, since for higher dimensions the numerical work
+ * explodes. Obviously, the matrix needs to be quadratic for this function.
*/
number determinant () const;
/**
- * Return the trace of the matrix,
- * i.e. the sum of the diagonal values
- * (which happens to also equal the sum
- * of the eigenvalues of a matrix).
- * Obviously, the matrix needs to
- * be quadratic for this function.
+ * Return the trace of the matrix, i.e. the sum of the diagonal values
+ * (which happens to also equal the sum of the eigenvalues of a matrix).
+ * Obviously, the matrix needs to be quadratic for this function.
*/
number trace () const;
const unsigned int precision=2) const;
/**
- * Print the matrix and allow
- * formatting of entries.
- *
- * The parameters allow for a
- * flexible setting of the output
- * format:
- *
- * @arg <tt>precision</tt>
- * denotes the number of trailing
- * digits.
- *
- * @arg <tt>scientific</tt> is
- * used to determine the number
- * format, where
- * <tt>scientific</tt> =
- * <tt>false</tt> means fixed
- * point notation.
- *
- * @arg <tt>width</tt> denotes
- * the with of each column. A
- * zero entry for <tt>width</tt>
- * makes the function compute a
- * width, but it may be changed
- * to a positive value, if output
- * is crude.
- *
- * @arg <tt>zero_string</tt>
- * specifies a string printed for
- * zero entries.
- *
- * @arg <tt>denominator</tt>
- * Multiply the whole matrix by
- * this common denominator to get
- * nicer numbers.
- *
- * @arg <tt>threshold</tt>: all
- * entries with absolute value
- * smaller than this are
- * considered zero.
+ * Print the matrix and allow formatting of entries.
+ *
+ * The parameters allow for a flexible setting of the output format:
+ *
+ * @arg <tt>precision</tt> denotes the number of trailing digits.
+ *
+ * @arg <tt>scientific</tt> is used to determine the number format, where
+ * <tt>scientific</tt> = <tt>false</tt> means fixed point notation.
+ *
+ * @arg <tt>width</tt> denotes the with of each column. A zero entry for
+ * <tt>width</tt> makes the function compute a width, but it may be changed
+ * to a positive value, if output is crude.
+ *
+ * @arg <tt>zero_string</tt> specifies a string printed for zero entries.
+ *
+ * @arg <tt>denominator</tt> Multiply the whole matrix by this common
+ * denominator to get nicer numbers.
+ *
+ * @arg <tt>threshold</tt>: all entries with absolute value smaller than
+ * this are considered zero.
*/
void print_formatted (std::ostream &out,
const unsigned int precision=3,
const double threshold = 0.) const;
/**
- * Determine an estimate for the
- * memory consumption (in bytes)
- * of this object.
+ * Determine an estimate for the memory consumption (in bytes) of this
+ * object.
*/
std::size_t memory_consumption () const;
//@{
/**
- * STL-like iterator with the
- * first entry.
+ * STL-like iterator with the first entry.
*/
const_iterator begin () const;
const_iterator end () const;
/**
- * STL-like iterator with the
- * first entry of row <tt>r</tt>.
+ * STL-like iterator with the first entry of row <tt>r</tt>.
*/
const_iterator begin (const size_type r) const;
//@{
/**
- * Scale the entire matrix by a
- * fixed factor.
+ * Scale the entire matrix by a fixed factor.
*/
FullMatrix &operator *= (const number factor);
/**
- * Scale the entire matrix by the
- * inverse of the given factor.
+ * Scale the entire matrix by the inverse of the given factor.
*/
FullMatrix &operator /= (const number factor);
/**
- * Simple addition of a scaled
- * matrix, i.e. <tt>*this +=
- * a*A</tt>.
+ * Simple addition of a scaled matrix, i.e. <tt>*this += a*A</tt>.
*
- * The matrix <tt>A</tt> may be a
- * full matrix over an arbitrary
- * underlying scalar type, as
- * long as its data type is
- * convertible to the data type
- * of this matrix.
+ * The matrix <tt>A</tt> may be a full matrix over an arbitrary underlying
+ * scalar type, as long as its data type is convertible to the data type of
+ * this matrix.
*/
template <typename number2>
void add (const number a,
const FullMatrix<number2> &A);
/**
- * Multiple addition of scaled
- * matrices, i.e. <tt>*this +=
- * a*A + b*B</tt>.
+ * Multiple addition of scaled matrices, i.e. <tt>*this += a*A + b*B</tt>.
*
- * The matrices <tt>A</tt> and
- * <tt>B</tt> may be a full
- * matrix over an arbitrary
- * underlying scalar type, as
- * long as its data type is
- * convertible to the data type
- * of this matrix.
+ * The matrices <tt>A</tt> and <tt>B</tt> may be a full matrix over an
+ * arbitrary underlying scalar type, as long as its data type is convertible
+ * to the data type of this matrix.
*/
template <typename number2>
void add (const number a,
const FullMatrix<number2> &B);
/**
- * Multiple addition of scaled
- * matrices, i.e. <tt>*this +=
- * a*A + b*B + c*C</tt>.
+ * Multiple addition of scaled matrices, i.e. <tt>*this += a*A + b*B +
+ * c*C</tt>.
*
- * The matrices <tt>A</tt>,
- * <tt>B</tt> and <tt>C</tt> may
- * be a full matrix over an
- * arbitrary underlying scalar
- * type, as long as its data type
- * is convertible to the data
- * type of this matrix.
+ * The matrices <tt>A</tt>, <tt>B</tt> and <tt>C</tt> may be a full matrix
+ * over an arbitrary underlying scalar type, as long as its data type is
+ * convertible to the data type of this matrix.
*/
template <typename number2>
void add (const number a,
/**
* Add rectangular block.
*
- * A rectangular block of the matrix
- * <tt>src</tt> is added to
- * <tt>this</tt>. The upper left corner
- * of the block being copied is
- * <tt>(src_offset_i,src_offset_j)</tt>.
- * The upper left corner of the copied
- * block is
- * <tt>(dst_offset_i,dst_offset_j)</tt>.
- * The size of the rectangular block
- * being copied is the maximum size
- * possible, determined either by the
- * size of <tt>this</tt> or <tt>src</tt>
- * and the given offsets.
+ * A rectangular block of the matrix <tt>src</tt> is added to
+ * <tt>this</tt>. The upper left corner of the block being copied is
+ * <tt>(src_offset_i,src_offset_j)</tt>. The upper left corner of the
+ * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>. The size of the
+ * rectangular block being copied is the maximum size possible, determined
+ * either by the size of <tt>this</tt> or <tt>src</tt> and the given
+ * offsets.
*/
template <typename number2>
void add (const FullMatrix<number2> &src,
const size_type src_offset_j = 0);
/**
- * Weighted addition of the
- * transpose of <tt>B</tt> to
- * <tt>this</tt>.
+ * Weighted addition of the transpose of <tt>B</tt> to <tt>this</tt>.
*
* <i>A += s B<sup>T</sup></i>
*/
/**
* Add transpose of a rectangular block.
*
- * A rectangular block of the
- * matrix <tt>src</tt> is
- * transposed and addedadded to
- * <tt>this</tt>. The upper left
- * corner of the block being
- * copied is
- * <tt>(src_offset_i,src_offset_j)</tt>
- * in the coordinates of the
- * <b>non</b>-transposed matrix.
- * The upper left corner of the
- * copied block is
- * <tt>(dst_offset_i,dst_offset_j)</tt>.
- * The size of the rectangular
- * block being copied is the
- * maximum size possible,
- * determined either by the size
- * of <tt>this</tt> or
- * <tt>src</tt>.
+ * A rectangular block of the matrix <tt>src</tt> is transposed and
+ * addedadded to <tt>this</tt>. The upper left corner of the block being
+ * copied is <tt>(src_offset_i,src_offset_j)</tt> in the coordinates of the
+ * <b>non</b>-transposed matrix. The upper left corner of the copied block
+ * is <tt>(dst_offset_i,dst_offset_j)</tt>. The size of the rectangular
+ * block being copied is the maximum size possible, determined either by the
+ * size of <tt>this</tt> or <tt>src</tt>.
*/
template <typename number2>
void Tadd (const FullMatrix<number2> &src,
const size_type src_offset_j = 0);
/**
- * Add a single element at the
- * given position.
+ * Add a single element at the given position.
*/
void add (const size_type row,
const size_type column,
const number value);
/**
- * Add an array of values given by
- * <tt>values</tt> in the given global
- * matrix row at columns specified by
- * col_indices in the full matrix. This
- * function is present for
- * compatibility with the various
- * sparse matrices in deal.II. In
- * particular, the two boolean fields
- * @p elide_zero_values and @p
- * col_indices_are_sorted do not impact
- * the performance of this routine, as
- * opposed to the sparse matrix case
- * and are indeed ignored in the
+ * Add an array of values given by <tt>values</tt> in the given global
+ * matrix row at columns specified by col_indices in the full matrix. This
+ * function is present for compatibility with the various sparse matrices in
+ * deal.II. In particular, the two boolean fields @p elide_zero_values and
+ * @p col_indices_are_sorted do not impact the performance of this routine,
+ * as opposed to the sparse matrix case and are indeed ignored in the
* implementation.
*/
template <typename number2, typename index_type>
const bool col_indices_are_sorted = false);
/**
- * <i>A(i,1...n) +=
- * s*A(j,1...n)</i>. Simple
- * addition of rows of this
+ * <i>A(i,1...n) += s*A(j,1...n)</i>. Simple addition of rows of this
*/
void add_row (const size_type i,
const number s,
const size_type j);
/**
- * <i>A(i,1...n) += s*A(j,1...n) +
- * t*A(k,1...n)</i>. Multiple
- * addition of rows of this.
+ * <i>A(i,1...n) += s*A(j,1...n) + t*A(k,1...n)</i>. Multiple addition of
+ * rows of this.
*/
void add_row (const size_type i,
const number s, const size_type j,
const number t, const size_type k);
/**
- * <i>A(1...n,i) += s*A(1...n,j)</i>.
- * Simple addition of columns of this.
+ * <i>A(1...n,i) += s*A(1...n,j)</i>. Simple addition of columns of this.
*/
void add_col (const size_type i,
const number s,
const size_type j);
/**
- * <i>A(1...n,i) += s*A(1...n,j) +
- * t*A(1...n,k)</i>. Multiple
- * addition of columns of this.
+ * <i>A(1...n,i) += s*A(1...n,j) + t*A(1...n,k)</i>. Multiple addition of
+ * columns of this.
*/
void add_col (const size_type i,
const number s, const size_type j,
const number t, const size_type k);
/**
- * Swap <i>A(i,1...n) <->
- * A(j,1...n)</i>. Swap rows i
- * and j of this
+ * Swap <i>A(i,1...n) <-> A(j,1...n)</i>. Swap rows i and j of this
*/
void swap_row (const size_type i,
const size_type j);
/**
- * Swap <i>A(1...n,i) <->
- * A(1...n,j)</i>. Swap columns
- * i and j of this
+ * Swap <i>A(1...n,i) <-> A(1...n,j)</i>. Swap columns i and j of this
*/
void swap_col (const size_type i,
const size_type j);
/**
- * Add constant to diagonal
- * elements of this, i.e. add a
- * multiple of the identity
- * matrix.
+ * Add constant to diagonal elements of this, i.e. add a multiple of the
+ * identity matrix.
*/
void diagadd (const number s);
/**
- * Assignment <tt>*this =
- * a*A</tt>.
+ * Assignment <tt>*this = a*A</tt>.
*/
template <typename number2>
void equ (const number a,
const FullMatrix<number2> &A);
/**
- * Assignment <tt>*this = a*A +
- * b*B</tt>.
+ * Assignment <tt>*this = a*A + b*B</tt>.
*/
template <typename number2>
void equ (const number a,
const FullMatrix<number2> &B);
/**
- * Assignment <tt>*this = a*A +
- * b*B + c*C</tt>.
+ * Assignment <tt>*this = a*A + b*B + c*C</tt>.
*/
template <typename number2>
void equ (const number a,
const FullMatrix<number2> &C);
/**
- * Symmetrize the matrix by
- * forming the mean value between
- * the existing matrix and its
- * transpose, <i>A =
- * 1/2(A+A<sup>T</sup>)</i>.
+ * Symmetrize the matrix by forming the mean value between the existing
+ * matrix and its transpose, <i>A = 1/2(A+A<sup>T</sup>)</i>.
*
- * Obviously the matrix must be
- * quadratic for this operation.
+ * Obviously the matrix must be quadratic for this operation.
*/
void symmetrize ();
/**
- * A=Inverse(A). A must be a square matrix.
- * Inversion of
- * this matrix by Gauss-Jordan
- * algorithm with partial
- * pivoting. This process is
- * well-behaved for positive
- * definite matrices, but be
- * aware of round-off errors in
- * the indefinite case.
- *
- * In case deal.II was configured with
- * LAPACK, the functions Xgetrf and
- * Xgetri build an LU factorization and
- * invert the matrix upon that
- * factorization, providing best
- * performance up to matrices with a
- * few hundreds rows and columns.
- *
- * The numerical effort to invert
- * an <tt>n x n</tt> matrix is of the
- * order <tt>n**3</tt>.
+ * A=Inverse(A). A must be a square matrix. Inversion of this matrix by
+ * Gauss-Jordan algorithm with partial pivoting. This process is
+ * well-behaved for positive definite matrices, but be aware of round-off
+ * errors in the indefinite case.
+ *
+ * In case deal.II was configured with LAPACK, the functions Xgetrf and
+ * Xgetri build an LU factorization and invert the matrix upon that
+ * factorization, providing best performance up to matrices with a few
+ * hundreds rows and columns.
+ *
+ * The numerical effort to invert an <tt>n x n</tt> matrix is of the order
+ * <tt>n**3</tt>.
*/
void gauss_jordan ();
/**
- * Assign the inverse of the given matrix
- * to <tt>*this</tt>. This function is
- * hardcoded for quadratic matrices of
- * dimension one to four. However, since
- * the amount of code needed grows
- * quickly, the method gauss_jordan() is
- * invoked implicitly if the dimension is
- * larger.
+ * Assign the inverse of the given matrix to <tt>*this</tt>. This function
+ * is hardcoded for quadratic matrices of dimension one to four. However,
+ * since the amount of code needed grows quickly, the method gauss_jordan()
+ * is invoked implicitly if the dimension is larger.
*/
template <typename number2>
void invert (const FullMatrix<number2> &M);
/**
- * Assign the Cholesky decomposition
- * of the given matrix to <tt>*this</tt>.
- * The given matrix must be symmetric
- * positive definite.
+ * Assign the Cholesky decomposition of the given matrix to <tt>*this</tt>.
+ * The given matrix must be symmetric positive definite.
*
- * ExcMatrixNotPositiveDefinite
- * will be thrown in the case that the
- * matrix is not positive definite.
+ * ExcMatrixNotPositiveDefinite will be thrown in the case that the matrix
+ * is not positive definite.
*/
template <typename number2>
void cholesky (const FullMatrix<number2> &A);
/**
- * <tt>*this(i,j)</tt> = $V(i) W(j)$
- * where $V,W$
- * are vectors of the same length.
+ * <tt>*this(i,j)</tt> = $V(i) W(j)$ where $V,W$ are vectors of the same
+ * length.
*/
template <typename number2>
void outer_product (const Vector<number2> &V,
const Vector<number2> &W);
/**
- * Assign the left_inverse of the given matrix
- * to <tt>*this</tt>. The calculation being
- * performed is <i>(A<sup>T</sup>*A)<sup>-1</sup>
+ * Assign the left_inverse of the given matrix to <tt>*this</tt>. The
+ * calculation being performed is <i>(A<sup>T</sup>*A)<sup>-1</sup>
* *A<sup>T</sup></i>.
*/
template <typename number2>
void left_invert (const FullMatrix<number2> &M);
/**
- * Assign the right_inverse of the given matrix
- * to <tt>*this</tt>. The calculation being
- * performed is <i>A<sup>T</sup>*(A*A<sup>T</sup>)
+ * Assign the right_inverse of the given matrix to <tt>*this</tt>. The
+ * calculation being performed is <i>A<sup>T</sup>*(A*A<sup>T</sup>)
* <sup>-1</sup></i>.
*/
template <typename number2>
/**
* Matrix-matrix-multiplication.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>C</tt> or added
- * to <tt>C</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
*
* if (adding)
* <i>C += A*B</i>
* if (!adding)
* <i>C = A*B</i>
*
- * Assumes that <tt>A</tt> and
- * <tt>B</tt> have compatible sizes and
- * that <tt>C</tt> already has the
- * right size.
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
*
- * This function uses the BLAS function
- * Xgemm if the calling matrix has more
- * than 15 rows and BLAS was detected
- * during configuration. Using BLAS
- * usually results in considerable
- * performance gains.
+ * This function uses the BLAS function Xgemm if the product of the three
+ * matrix dimensions is larger than 300 and BLAS was detected during
+ * configuration. Using BLAS usually results in considerable performance
+ * gains.
*/
template <typename number2>
void mmult (FullMatrix<number2> &C,
const bool adding=false) const;
/**
- * Matrix-matrix-multiplication using
- * transpose of <tt>this</tt>.
+ * Matrix-matrix-multiplication using transpose of <tt>this</tt>.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>C</tt> or added
- * to <tt>C</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
*
* if (adding)
* <i>C += A<sup>T</sup>*B</i>
* if (!adding)
* <i>C = A<sup>T</sup>*B</i>
*
- * Assumes that <tt>A</tt> and
- * <tt>B</tt> have compatible
- * sizes and that <tt>C</tt>
- * already has the right size.
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
*
- * This function uses the BLAS function
- * Xgemm if the calling matrix has more
- * than 15 columns and BLAS was
- * detected during configuration. Using
- * BLAS usually results in considerable
- * performance gains.
+ * This function uses the BLAS function Xgemm if the product of the three
+ * matrix dimensions is larger than 300 and BLAS was detected during
+ * configuration. Using BLAS usually results in considerable performance
+ * gains.
*/
template <typename number2>
void Tmmult (FullMatrix<number2> &C,
const bool adding=false) const;
/**
- * Matrix-matrix-multiplication using
- * transpose of <tt>B</tt>.
+ * Matrix-matrix-multiplication using transpose of <tt>B</tt>.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>C</tt> or added
- * to <tt>C</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
*
* if (adding)
* <i>C += A*B<sup>T</sup></i>
* if (!adding)
* <i>C = A*B<sup>T</sup></i>
*
- * Assumes that <tt>A</tt> and
- * <tt>B</tt> have compatible sizes and
- * that <tt>C</tt> already has the
- * right size.
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
*
- * This function uses the BLAS function
- * Xgemm if the calling matrix has more
- * than 15 rows and BLAS was detected
- * during configuration. Using BLAS
- * usually results in considerable
- * performance gains.
+ * This function uses the BLAS function Xgemm if the product of the three
+ * matrix dimensions is larger than 300 and BLAS was detected during
+ * configuration. Using BLAS usually results in considerable performance
+ * gains.
*/
template <typename number2>
void mTmult (FullMatrix<number2> &C,
const bool adding=false) const;
/**
- * Matrix-matrix-multiplication using
- * transpose of <tt>this</tt> and
+ * Matrix-matrix-multiplication using transpose of <tt>this</tt> and
* <tt>B</tt>.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>C</tt> or added
- * to <tt>C</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
*
* if (adding)
* <i>C += A<sup>T</sup>*B<sup>T</sup></i>
* if (!adding)
* <i>C = A<sup>T</sup>*B<sup>T</sup></i>
*
- * Assumes that <tt>A</tt> and
- * <tt>B</tt> have compatible
- * sizes and that <tt>C</tt>
- * already has the right size.
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
*
- * This function uses the BLAS function
- * Xgemm if the calling matrix has more
- * than 15 columns and BLAS was
- * detected during configuration. Using
- * BLAS usually results in considerable
- * performance gains.
+ * This function uses the BLAS function Xgemm if the product of the three
+ * matrix dimensions is larger than 300 and BLAS was detected during
+ * configuration. Using BLAS usually results in considerable performance
+ * gains.
*/
template <typename number2>
void TmTmult (FullMatrix<number2> &C,
const bool adding=false) const;
/**
- * Add to the current matrix the
- * triple product <b>B A
- * D</b>. Optionally, use the
- * transposes of the matrices
- * <b>B</b> and <b>D</b>. The
- * scaling factor scales the
- * whole product, which is
- * helpful when adding a multiple
- * of the triple product to the
- * matrix.
- *
- * This product was written with
- * the Schur complement
- * <b>B<sup>T</sup>
- * A<sup>-1</sup> D</b> in mind.
- * Note that in this case the
- * argument for <tt>A</tt> must be
- * the inverse of the matrix <b>A</b>.
+ * Add to the current matrix the triple product <b>B A D</b>. Optionally,
+ * use the transposes of the matrices <b>B</b> and <b>D</b>. The scaling
+ * factor scales the whole product, which is helpful when adding a multiple
+ * of the triple product to the matrix.
+ *
+ * This product was written with the Schur complement <b>B<sup>T</sup>
+ * A<sup>-1</sup> D</b> in mind. Note that in this case the argument for
+ * <tt>A</tt> must be the inverse of the matrix <b>A</b>.
*/
void triple_product(const FullMatrix<number> &A,
const FullMatrix<number> &B,
/**
* Matrix-vector-multiplication.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>w</tt> or added
- * to <tt>w</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>w</tt> or added to <tt>w</tt>.
*
* if (adding)
* <i>w += A*v</i>
* if (!adding)
* <i>w = A*v</i>
*
- * Source and destination must
- * not be the same vector.
+ * Source and destination must not be the same vector.
*/
template <typename number2>
void vmult (Vector<number2> &w,
const bool adding=false) const;
/**
- * Adding Matrix-vector-multiplication.
- * <i>w += A*v</i>
+ * Adding Matrix-vector-multiplication. <i>w += A*v</i>
*
- * Source and destination must
- * not be the same vector.
+ * Source and destination must not be the same vector.
*/
template <typename number2>
void vmult_add (Vector<number2> &w,
const Vector<number2> &v) const;
/**
- * Transpose
- * matrix-vector-multiplication.
+ * Transpose matrix-vector-multiplication.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>w</tt> or added
- * to <tt>w</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>w</tt> or added to <tt>w</tt>.
*
* if (adding)
* <i>w += A<sup>T</sup>*v</i>
* <i>w = A<sup>T</sup>*v</i>
*
*
- * Source and destination must
- * not be the same vector.
+ * Source and destination must not be the same vector.
*/
template <typename number2>
void Tvmult (Vector<number2> &w,
const bool adding=false) const;
/**
- * Adding transpose
- * matrix-vector-multiplication.
- * <i>w += A<sup>T</sup>*v</i>
+ * Adding transpose matrix-vector-multiplication. <i>w +=
+ * A<sup>T</sup>*v</i>
*
- * Source and destination must
- * not be the same vector.
+ * Source and destination must not be the same vector.
*/
template <typename number2>
void Tvmult_add (Vector<number2> &w,
const Vector<number2> &v) const;
/**
- * Apply the Jacobi
- * preconditioner, which
- * multiplies every element of
- * the <tt>src</tt> vector by the
- * inverse of the respective
- * diagonal element and
- * multiplies the result with the
- * damping factor <tt>omega</tt>.
+ * Apply the Jacobi preconditioner, which multiplies every element of the
+ * <tt>src</tt> vector by the inverse of the respective diagonal element and
+ * multiplies the result with the damping factor <tt>omega</tt>.
*/
template <typename somenumber>
void precondition_Jacobi (Vector<somenumber> &dst,
const number omega = 1.) const;
/**
- * <i>dst=b-A*x</i>. Residual calculation,
- * returns the <i>l<sub>2</sub></i>-norm
- * |<i>dst</i>|.
+ * <i>dst=b-A*x</i>. Residual calculation, returns the
+ * <i>l<sub>2</sub></i>-norm |<i>dst</i>|.
*
- * Source <i>x</i> and destination
- * <i>dst</i> must not be the same
- * vector.
+ * Source <i>x</i> and destination <i>dst</i> must not be the same vector.
*/
template <typename number2, typename number3>
number residual (Vector<number2> &dst,
const Vector<number3> &b) const;
/**
- * Forward elimination of lower
- * triangle. Inverts the lower
- * triangle of a rectangular matrix
- * for a given right hand side.
+ * Forward elimination of lower triangle. Inverts the lower triangle of a
+ * rectangular matrix for a given right hand side.
*
- * If the matrix has more columns
- * than rows, this function only
- * operates on the left quadratic
- * submatrix. If there are more
- * rows, the upper quadratic part
- * of the matrix is considered.
+ * If the matrix has more columns than rows, this function only operates on
+ * the left quadratic submatrix. If there are more rows, the upper quadratic
+ * part of the matrix is considered.
*
- * @note It is safe to use the
- * same object for @p dst and @p
- * src.
+ * @note It is safe to use the same object for @p dst and @p src.
*/
template <typename number2>
void forward (Vector<number2> &dst,
const Vector<number2> &src) const;
/**
- * Backward elimination of upper
- * triangle.
+ * Backward elimination of upper triangle.
*
* See forward()
*
- * @note It is safe to use the
- * same object for @p dst and @p
- * src.
+ * @note It is safe to use the same object for @p dst and @p src.
*/
template <typename number2>
void backward (Vector<number2> &dst,
const number alpha = 1.;
const number beta = (adding == true) ? 1. : 0.;
- // Use the BLAS function gemm for
- // calculating the matrix-matrix
+ // Use the BLAS function gemm for calculating the matrix-matrix
// product.
gemm(notrans, notrans, &m, &n, &k, &alpha, &src(0,0), &m,
&this->values[0], &k, &beta, &dst(0,0), &m);
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
typedef types::global_dof_index size_type;
/**
- * Constructor. Initialize the
- * matrix as a square matrix with
- * dimension <tt>n</tt>.
+ * Constructor. Initialize the matrix as a square matrix with dimension
+ * <tt>n</tt>.
*
- * In order to avoid the implicit
- * conversion of integers and
- * other types to a matrix, this
- * constructor is declared
- * <tt>explicit</tt>.
+ * In order to avoid the implicit conversion of integers and other types to
+ * a matrix, this constructor is declared <tt>explicit</tt>.
*
- * By default, no memory is
- * allocated.
+ * By default, no memory is allocated.
*/
explicit LAPACKFullMatrix (const size_type n = 0);
/**
- * Constructor. Initialize the
- * matrix as a rectangular
- * matrix.
+ * Constructor. Initialize the matrix as a rectangular matrix.
*/
LAPACKFullMatrix (const size_type rows,
const size_type cols);
/**
- * Copy constructor. This
- * constructor does a deep copy
- * of the matrix. Therefore, it
- * poses a possible efficiency
- * problem, if for example,
- * function arguments are passed
- * by value rather than by
- * reference. Unfortunately, we
- * can't mark this copy
- * constructor <tt>explicit</tt>,
- * since that prevents the use of
- * this class in containers, such
- * as <tt>std::vector</tt>. The
- * responsibility to check
- * performance of programs must
- * therefore remain with the
- * user of this class.
+ * Copy constructor. This constructor does a deep copy of the
+ * matrix. Therefore, it poses a possible efficiency problem, if for
+ * example, function arguments are passed by value rather than by
+ * reference. Unfortunately, we can't mark this copy constructor
+ * <tt>explicit</tt>, since that prevents the use of this class in
+ * containers, such as <tt>std::vector</tt>. The responsibility to check
+ * performance of programs must therefore remain with the user of this
+ * class.
*/
LAPACKFullMatrix (const LAPACKFullMatrix &);
operator = (const LAPACKFullMatrix<number> &);
/**
- * Assignment operator for a
- * regular FullMatrix. Note that
- * since LAPACK expects matrices
- * in transposed order, this
- * transposition is included here.
+ * Assignment operator for a regular FullMatrix. Note that since LAPACK
+ * expects matrices in transposed order, this transposition is included
+ * here.
*/
template <typename number2>
LAPACKFullMatrix<number> &
operator = (const FullMatrix<number2> &);
/**
- * This operator assigns a scalar
- * to a matrix. To avoid
- * confusion with constructors,
- * zero is the only value allowed
- * for <tt>d</tt>
+ * This operator assigns a scalar to a matrix. To avoid confusion with
+ * constructors, zero is the only value allowed for <tt>d</tt>
*/
LAPACKFullMatrix<number> &
operator = (const double d);
/**
- * Assignment from different
- * matrix classes, performing the
- * usual conversion to the
- * transposed format expected by LAPACK. This
- * assignment operator uses
- * iterators of the class
- * MATRIX. Therefore, sparse
- * matrices are possible sources.
+ * Assignment from different matrix classes, performing the usual conversion
+ * to the transposed format expected by LAPACK. This assignment operator
+ * uses iterators of the class MATRIX. Therefore, sparse matrices are
+ * possible sources.
*/
template <class MATRIX>
void copy_from (const MATRIX &);
/**
* Fill rectangular block.
*
- * A rectangular block of the
- * matrix <tt>src</tt> is copied into
- * <tt>this</tt>. The upper left
- * corner of the block being
- * copied is
- * <tt>(src_offset_i,src_offset_j)</tt>.
- * The upper left corner of the
- * copied block is
- * <tt>(dst_offset_i,dst_offset_j)</tt>.
- * The size of the rectangular
- * block being copied is the
- * maximum size possible,
- * determined either by the size
- * of <tt>this</tt> or <tt>src</tt>.
- *
- * The final two arguments allow
- * to enter a multiple of the
- * source or its transpose.
+ * A rectangular block of the matrix <tt>src</tt> is copied into
+ * <tt>this</tt>. The upper left corner of the block being copied is
+ * <tt>(src_offset_i,src_offset_j)</tt>. The upper left corner of the
+ * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>. The size of the
+ * rectangular block being copied is the maximum size possible, determined
+ * either by the size of <tt>this</tt> or <tt>src</tt>.
+ *
+ * The final two arguments allow to enter a multiple of the source or its
+ * transpose.
*/
template<class MATRIX>
void fill (const MATRIX &src,
/**
* Matrix-vector-multiplication.
*
- * Depending on previous
- * transformations recorded in #state, the
- * result of this function is one
- * of
- *
- * <ul>
- * <li> If #state is LAPACKSupport::matrix or
- * LAPACKSupport::inverse_matrix,
- * this will be a regular matrix
- * vector product using LAPACK
- * gemv().
- * <li> If #state is
- * LAPACKSupport::svd or
- * LAPACKSupport::inverse_svd,
- * this function first multiplies
- * with the right transformation
- * matrix, then with the diagonal
- * matrix of singular values or
- * their reciprocal values, and
- * finally with the left
- * trandformation matrix.
- * </ul>
- *
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>w</tt> or added
- * to <tt>w</tt>.
+ * Depending on previous transformations recorded in #state, the result of
+ * this function is one of
+ * <ul>
+ * <li> If #state is LAPACKSupport::matrix or LAPACKSupport::inverse_matrix,
+ * this will be a regular matrix vector product using LAPACK gemv().
+ * <li> If #state is LAPACKSupport::svd or LAPACKSupport::inverse_svd, this
+ * function first multiplies with the right transformation matrix, then with
+ * the diagonal matrix of singular values or their reciprocal values, and
+ * finally with the left trandformation matrix.
+ * </ul>
+ *
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>w</tt> or added to <tt>w</tt>.
*
* if (adding)
* <i>w += A*v</i>
* if (!adding)
* <i>w = A*v</i>
*
- * @note Source and destination must
- * not be the same vector.
+ * @note Source and destination must not be the same vector.
*
- * @note This template only
- * exists for compile-time
- * compatibility with
- * FullMatrix. Implementation is
- * only available for <tt>VECTOR=Vector<number></tt>
+ * @note This template only exists for compile-time compatibility with
+ * FullMatrix. Implementation is only available for
+ * <tt>VECTOR=Vector<number></tt>
*/
template <class VECTOR>
void vmult(VECTOR &dst, const VECTOR &src, const bool adding = false) const;
+
/**
- * Adding Matrix-vector-multiplication.
- * <i>w += A*v</i>
+ * Adding Matrix-vector-multiplication. <i>w += A*v</i>
*
- * See the documentation of
- * vmult() for details on the
- * implementation.
+ * See the documentation of vmult() for details on the implementation.
*/
template <class VECTOR>
void vmult_add (VECTOR &w, const VECTOR &v) const;
/**
- * Transpose
- * matrix-vector-multiplication.
+ * Transpose matrix-vector-multiplication.
*
- * The optional parameter
- * <tt>adding</tt> determines, whether the
- * result is stored in <tt>w</tt> or added
- * to <tt>w</tt>.
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>w</tt> or added to <tt>w</tt>.
*
* if (adding)
* <i>w += A<sup>T</sup>*v</i>
* if (!adding)
* <i>w = A<sup>T</sup>*v</i>
*
- * See the documentation of
- * vmult() for details on the
- * implementation.
+ * See the documentation of vmult() for details on the implementation.
*/
template <class VECTOR>
void Tvmult (VECTOR &w, const VECTOR &v,
const bool adding=false) const;
/**
- * Adding transpose
- * matrix-vector-multiplication.
- * <i>w += A<sup>T</sup>*v</i>
+ * Adding transpose matrix-vector-multiplication. <i>w +=
+ * A<sup>T</sup>*v</i>
*
- * See the documentation of
- * vmult() for details on the
- * implementation.
+ * See the documentation of vmult() for details on the implementation.
*/
template <class VECTOR>
void Tvmult_add (VECTOR &w, const VECTOR &v) const;
const bool adding=false) const;
void Tvmult_add (Vector<number> &w,
const Vector<number> &v) const;
+
+
+ /**
+ * Matrix-matrix-multiplication.
+ *
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
+ *
+ * if (adding)
+ * <i>C += A*B</i>
+ *
+ * if (!adding)
+ * <i>C = A*B</i>
+ *
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
+ *
+ * This function uses the BLAS function Xgemm.
+ */
+ void mmult (LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Same as before, but stores the result in a FullMatrix, not in a
+ * LAPACKFullMatrix.
+ */
+ void mmult (FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Matrix-matrix-multiplication using transpose of <tt>this</tt>.
+ *
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
+ *
+ * if (adding)
+ * <i>C += A<sup>T</sup>*B</i>
+ *
+ * if (!adding)
+ * <i>C = A<sup>T</sup>*B</i>
+ *
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
+ *
+ * This function uses the BLAS function Xgemm.
+ */
+ void Tmmult (LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Same as before, but stores the result in a FullMatrix, not in a
+ * LAPACKFullMatrix.
+ */
+ void Tmmult (FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Matrix-matrix-multiplication using transpose of <tt>B</tt>.
+ *
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
+ *
+ * if (adding)
+ * <i>C += A*B<sup>T</sup></i>
+ *
+ * if (!adding)
+ * <i>C = A*B<sup>T</sup></i>
+ *
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
+ *
+ * This function uses the BLAS function Xgemm.
+ */
+ void mTmult (LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
/**
- * Compute the LU factorization
- * of the matrix using LAPACK
- * function Xgetrf.
+ * Same as before, but stores the result in a FullMatrix, not in a
+ * LAPACKFullMatrix.
+ */
+ void mTmult (FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Matrix-matrix-multiplication using transpose of <tt>this</tt> and
+ * <tt>B</tt>.
+ *
+ * The optional parameter <tt>adding</tt> determines, whether the result is
+ * stored in <tt>C</tt> or added to <tt>C</tt>.
+ *
+ * if (adding)
+ * <i>C += A<sup>T</sup>*B<sup>T</sup></i>
+ *
+ * if (!adding)
+ * <i>C = A<sup>T</sup>*B<sup>T</sup></i>
+ *
+ * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+ * <tt>C</tt> already has the right size.
+ *
+ * This function uses the BLAS function Xgemm.
+ */
+ void TmTmult (LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Same as before, but stores the result in a FullMatrix, not in a
+ * LAPACKFullMatrix.
+ */
+ void TmTmult (FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding=false) const;
+
+ /**
+ * Compute the LU factorization of the matrix using LAPACK function Xgetrf.
*/
void compute_lu_factorization ();
/**
- * Invert the matrix by first computing
- * an LU factorization with the LAPACK
- * function Xgetrf and then building
- * the actual inverse using Xgetri.
+ * Invert the matrix by first computing an LU factorization with the LAPACK
+ * function Xgetrf and then building the actual inverse using Xgetri.
*/
void invert ();
/**
- * Solve the linear system with
- * right hand side given by
- * applying forward/backward
- * substitution to the previously
- * computed LU
- * factorization. Uses LAPACK
- * function Xgetrs.
+ * Solve the linear system with right hand side given by applying
+ * forward/backward substitution to the previously computed LU
+ * factorization. Uses LAPACK function Xgetrs.
+ *
+ * The flag transposed indicates whether the solution of the transposed
+ * system is to be performed.
*/
void apply_lu_factorization (Vector<number> &v,
const bool transposed) const;
/**
- * Compute eigenvalues of the
- * matrix. After this routine has
- * been called, eigenvalues can
- * be retrieved using the
- * eigenvalue() function. The
- * matrix itself will be
- * LAPACKSupport::unusable after
- * this operation.
- *
- * The optional arguments allow
- * to compute left and right
- * eigenvectors as well.
- *
- * Note that the function does
- * not return the computed
- * eigenvalues right away since
- * that involves copying data
- * around between the output
- * arrays of the LAPACK functions
- * and any return array. This is
- * often unnecessary since one
- * may not be interested in all
- * eigenvalues at once, but for
- * example only the extreme
- * ones. In that case, it is
- * cheaper to just have this
- * function compute the
- * eigenvalues and have a
- * separate function that returns
- * whatever eigenvalue is
- * requested.
- *
- * @note Calls the LAPACK
- * function Xgeev.
+ * Solve the linear system with multiple right hand sides (as many as there
+ * are columns in the matrix b) given by applying forward/backward
+ * substitution to the previously computed LU factorization. Uses LAPACK
+ * function Xgetrs.
+ *
+ * The flag transposed indicates whether the solution of the transposed
+ * system is to be performed.
+ */
+ void apply_lu_factorization (LAPACKFullMatrix<number> &B,
+ const bool transposed) const;
+
+ /**
+ * Compute eigenvalues of the matrix. After this routine has been called,
+ * eigenvalues can be retrieved using the eigenvalue() function. The matrix
+ * itself will be LAPACKSupport::unusable after this operation.
+ *
+ * The optional arguments allow to compute left and right eigenvectors as
+ * well.
+ *
+ * Note that the function does not return the computed eigenvalues right
+ * away since that involves copying data around between the output arrays of
+ * the LAPACK functions and any return array. This is often unnecessary
+ * since one may not be interested in all eigenvalues at once, but for
+ * example only the extreme ones. In that case, it is cheaper to just have
+ * this function compute the eigenvalues and have a separate function that
+ * returns whatever eigenvalue is requested.
+ *
+ * @note Calls the LAPACK function Xgeev.
*/
void compute_eigenvalues (const bool right_eigenvectors = false,
const bool left_eigenvectors = false);
/**
- * Compute eigenvalues and
- * eigenvectors of a real symmetric
- * matrix. Only eigenvalues in the
- * interval (lower_bound, upper_bound]
- * are computed with the absolute
- * tolerance abs_accuracy. An approximate
- * eigenvalue is accepted as converged
- * when it is determined to lie in an
- * interval [a,b] of width less than or
- * equal to abs_accuracy + eps * max( |a|,|b| ),
- * where eps is the machine precision.
- * If abs_accuracy is less than
- * or equal to zero, then eps*|t| will
- * be used in its place, where |t| is the
- * 1-norm of the tridiagonal matrix obtained
- * by reducing A to tridiagonal form.
- * Eigenvalues will be computed most accurately
- * when abs_accuracy is set to twice the
- * underflow threshold, not zero.
- * After this routine has
- * been called, all eigenvalues in
- * (lower_bound, upper_bound] will be
- * stored in eigenvalues and the
- * corresponding eigenvectors will be stored
- * in the columns of eigenvectors, whose
- * dimension is set accordingly.
- *
- * @note Calls the LAPACK function
- * Xsyevx. For this to work, ./configure
- * has to be told to use LAPACK.
+ * Compute eigenvalues and eigenvectors of a real symmetric matrix. Only
+ * eigenvalues in the interval (lower_bound, upper_bound] are computed with
+ * the absolute tolerance abs_accuracy. An approximate eigenvalue is
+ * accepted as converged when it is determined to lie in an interval [a,b]
+ * of width less than or equal to abs_accuracy + eps * max( |a|,|b| ), where
+ * eps is the machine precision. If abs_accuracy is less than or equal to
+ * zero, then eps*|t| will be used in its place, where |t| is the 1-norm of
+ * the tridiagonal matrix obtained by reducing A to tridiagonal form.
+ * Eigenvalues will be computed most accurately when abs_accuracy is set to
+ * twice the underflow threshold, not zero. After this routine has been
+ * called, all eigenvalues in (lower_bound, upper_bound] will be stored in
+ * eigenvalues and the corresponding eigenvectors will be stored in the
+ * columns of eigenvectors, whose dimension is set accordingly.
+ *
+ * @note Calls the LAPACK function Xsyevx. For this to work, ./configure has
+ * to be told to use LAPACK.
*/
void compute_eigenvalues_symmetric(
const number lower_bound,
FullMatrix<number> &eigenvectors);
/**
- * Compute generalized eigenvalues
- * and eigenvectors of
- * a real generalized symmetric
- * eigenproblem of the form
- * itype = 1: $Ax=\lambda B x$
- * itype = 2: $ABx=\lambda x$
- * itype = 3: $BAx=\lambda x$,
- * where A is this matrix.
- * A and B are assumed to be symmetric,
- * and B has to be positive definite.
- * Only eigenvalues in the interval
- * (lower_bound, upper_bound] are
- * computed with the absolute tolerance
- * abs_accuracy.
- * An approximate eigenvalue is accepted
- * as converged when it is determined to
- * lie in an interval [a,b] of width less
- * than or equal to abs_accuracy + eps * max( |a|,|b| ),
- * where eps is the machine precision.
- * If abs_accuracy is less than
- * or equal to zero, then eps*|t| will
- * be used in its place, where |t| is the
- * 1-norm of the tridiagonal matrix obtained
- * by reducing A to tridiagonal form.
- * Eigenvalues will be computed most accurately
- * when abs_accuracy is set to twice the
- * underflow threshold, not zero.
- * After this routine has
- * been called, all eigenvalues in
- * (lower_bound, upper_bound] will be
- * stored in eigenvalues and the
- * corresponding eigenvectors will be stored
- * in eigenvectors, whose dimension is set
- * accordingly.
- *
- * @note Calls the LAPACK
- * function Xsygvx. For this to
- * work, ./configure has to
- * be told to use LAPACK.
+ * Compute generalized eigenvalues and eigenvectors of a real generalized
+ * symmetric eigenproblem of the form itype = 1: $Ax=\lambda B x$ itype = 2:
+ * $ABx=\lambda x$ itype = 3: $BAx=\lambda x$, where A is this matrix. A
+ * and B are assumed to be symmetric, and B has to be positive definite.
+ * Only eigenvalues in the interval (lower_bound, upper_bound] are computed
+ * with the absolute tolerance abs_accuracy. An approximate eigenvalue is
+ * accepted as converged when it is determined to lie in an interval [a,b]
+ * of width less than or equal to abs_accuracy + eps * max( |a|,|b| ), where
+ * eps is the machine precision. If abs_accuracy is less than or equal to
+ * zero, then eps*|t| will be used in its place, where |t| is the 1-norm of
+ * the tridiagonal matrix obtained by reducing A to tridiagonal form.
+ * Eigenvalues will be computed most accurately when abs_accuracy is set to
+ * twice the underflow threshold, not zero. After this routine has been
+ * called, all eigenvalues in (lower_bound, upper_bound] will be stored in
+ * eigenvalues and the corresponding eigenvectors will be stored in
+ * eigenvectors, whose dimension is set accordingly.
+ *
+ * @note Calls the LAPACK function Xsygvx. For this to work, ./configure has
+ * to be told to use LAPACK.
*/
void compute_generalized_eigenvalues_symmetric(
LAPACKFullMatrix<number> &B,
const int itype = 1);
/**
- * Same as the other
- * compute_generalized_eigenvalues_symmetric
- * function except that all
- * eigenvalues are computed
- * and the tolerance is set
- * automatically.
- * Note that this function does
- * not return the computed
- * eigenvalues right away since
- * that involves copying data
- * around between the output
- * arrays of the LAPACK functions
- * and any return array. This is
- * often unnecessary since one
- * may not be interested in all
- * eigenvalues at once, but for
- * example only the extreme
- * ones. In that case, it is
- * cheaper to just have this
- * function compute the
- * eigenvalues and have a
- * separate function that returns
- * whatever eigenvalue is
- * requested. Eigenvalues can
- * be retrieved using the
- * eigenvalue() function.
- * The number of computed
- * eigenvectors is equal
- * to eigenvectors.size()
- *
- * @note Calls the LAPACK
- * function Xsygv. For this to
- * work, ./configure has to
- * be told to use LAPACK.
+ * Same as the other compute_generalized_eigenvalues_symmetric function
+ * except that all eigenvalues are computed and the tolerance is set
+ * automatically. Note that this function does not return the computed
+ * eigenvalues right away since that involves copying data around between
+ * the output arrays of the LAPACK functions and any return array. This is
+ * often unnecessary since one may not be interested in all eigenvalues at
+ * once, but for example only the extreme ones. In that case, it is cheaper
+ * to just have this function compute the eigenvalues and have a separate
+ * function that returns whatever eigenvalue is requested. Eigenvalues can
+ * be retrieved using the eigenvalue() function. The number of computed
+ * eigenvectors is equal to eigenvectors.size()
+ *
+ * @note Calls the LAPACK function Xsygv. For this to work, ./configure has
+ * to be told to use LAPACK.
*/
void compute_generalized_eigenvalues_symmetric (
LAPACKFullMatrix<number> &B,
const int itype = 1);
/**
- * Compute the singular value
- * decomposition of the
- * matrix using LAPACK function
- * Xgesdd.
+ * Compute the singular value decomposition of the matrix using LAPACK
+ * function Xgesdd.
*
- * Requires that the #state is
- * LAPACKSupport::matrix, fills
- * the data members #wr, #svd_u,
- * and #svd_vt, and leaves the
- * object in the #state
+ * Requires that the #state is LAPACKSupport::matrix, fills the data members
+ * #wr, #svd_u, and #svd_vt, and leaves the object in the #state
* LAPACKSupport::svd.
*/
void compute_svd();
+
/**
- * Compute the inverse of the
- * matrix by singular value
- * decomposition.
- *
- * Requires that #state is either
- * LAPACKSupport::matrix or
- * LAPACKSupport::svd. In the
- * first case, this function
- * calls compute_svd(). After
- * this function, the object will
- * have the #state
+ * Compute the inverse of the matrix by singular value decomposition.
+ *
+ * Requires that #state is either LAPACKSupport::matrix or
+ * LAPACKSupport::svd. In the first case, this function calls
+ * compute_svd(). After this function, the object will have the #state
* LAPACKSupport::inverse_svd.
*
- * For a singular value
- * decomposition, the inverse is
- * simply computed by replacing
- * all singular values by their
- * reciprocal values. If the
- * matrix does not have maximal
- * rank, singular values 0 are
- * not touched, thus computing
- * the minimal norm right inverse
- * of the matrix.
- *
- * The parameter
- * <tt>threshold</tt> determines,
- * when a singular value should
- * be considered zero. It is the
- * ratio of the smallest to the
- * largest nonzero singular
- * value
- * <i>s</i><sub>max</sub>. Thus,
- * the inverses of all singular
- * values less than
- * <i>s</i><sub>max</sub>/<tt>threshold</tt>
- * will be set to zero.
+ * For a singular value decomposition, the inverse is simply computed by
+ * replacing all singular values by their reciprocal values. If the matrix
+ * does not have maximal rank, singular values 0 are not touched, thus
+ * computing the minimal norm right inverse of the matrix.
+ *
+ * The parameter <tt>threshold</tt> determines, when a singular value should
+ * be considered zero. It is the ratio of the smallest to the largest
+ * nonzero singular value <i>s</i><sub>max</sub>. Thus, the inverses of all
+ * singular values less than <i>s</i><sub>max</sub>/<tt>threshold</tt> will
+ * be set to zero.
*/
void compute_inverse_svd (const double threshold = 0.);
/**
- * Retrieve eigenvalue after
- * compute_eigenvalues() was
- * called.
+ * Retrieve eigenvalue after compute_eigenvalues() was called.
*/
std::complex<number>
eigenvalue (const size_type i) const;
/**
- * Retrieve singular values after
- * compute_svd() or
- * compute_inverse_svd() was
+ * Retrieve singular values after compute_svd() or compute_inverse_svd() was
* called.
*/
number
singular_value (const size_type i) const;
/**
- * Print the matrix and allow
- * formatting of entries.
- *
- * The parameters allow for a
- * flexible setting of the output
- * format:
- *
- * @arg <tt>precision</tt>
- * denotes the number of trailing
- * digits.
- *
- * @arg <tt>scientific</tt> is
- * used to determine the number
- * format, where
- * <tt>scientific</tt> =
- * <tt>false</tt> means fixed
- * point notation.
- *
- * @arg <tt>width</tt> denotes
- * the with of each column. A
- * zero entry for <tt>width</tt>
- * makes the function compute a
- * width, but it may be changed
- * to a positive value, if output
- * is crude.
- *
- * @arg <tt>zero_string</tt>
- * specifies a string printed for
- * zero entries.
- *
- * @arg <tt>denominator</tt>
- * Multiply the whole matrix by
- * this common denominator to get
- * nicer numbers.
- *
- * @arg <tt>threshold</tt>: all
- * entries with absolute value
- * smaller than this are
- * considered zero.
+ * Print the matrix and allow formatting of entries.
+ *
+ * The parameters allow for a flexible setting of the output format:
+ *
+ * @arg <tt>precision</tt> denotes the number of trailing digits.
+ *
+ * @arg <tt>scientific</tt> is used to determine the number format, where
+ * <tt>scientific</tt> = <tt>false</tt> means fixed point notation.
+ *
+ * @arg <tt>width</tt> denotes the with of each column. A zero entry for
+ * <tt>width</tt> makes the function compute a width, but it may be changed
+ * to a positive value, if output is crude.
+ *
+ * @arg <tt>zero_string</tt> specifies a string printed for zero entries.
+ *
+ * @arg <tt>denominator</tt> Multiply the whole matrix by this common
+ * denominator to get nicer numbers.
+ *
+ * @arg <tt>threshold</tt>: all entries with absolute value smaller than
+ * this are considered zero.
*/
void print_formatted (std::ostream &out,
const unsigned int presicion=3,
private:
/**
- * Since LAPACK operations
- * notoriously change the meaning
- * of the matrix entries, we
- * record the current state after
- * the last operation here.
+ * Since LAPACK operations notoriously change the meaning of the matrix
+ * entries, we record the current state after the last operation here.
*/
LAPACKSupport::State state;
+
/**
- * Additional properties of the
- * matrix which may help to
- * select more efficient LAPACK
- * functions.
+ * Additional properties of the matrix which may help to select more
+ * efficient LAPACK functions.
*/
LAPACKSupport::Properties properties;
/**
- * The working array used for
- * some LAPACK functions.
+ * The working array used for some LAPACK functions.
*/
mutable std::vector<number> work;
/**
- * The vector storing the
- * permutations applied for
- * pivoting in the
+ * The vector storing the permutations applied for pivoting in the
* LU-factorization.
*
- * Also used as the scratch array
- * IWORK for LAPACK functions
- * needing it.
+ * Also used as the scratch array IWORK for LAPACK functions needing it.
*/
std::vector<int> ipiv;
/**
- * Workspace for calculating the
- * inverse matrix from an LU
- * factorization.
+ * Workspace for calculating the inverse matrix from an LU factorization.
*/
std::vector<number> inv_work;
/**
- * Real parts of eigenvalues or
- * the singular values. Filled by
+ * Real parts of eigenvalues or the singular values. Filled by
* compute_eigenvalues() or compute_svd().
*/
std::vector<number> wr;
/**
- * Imaginary parts of
- * eigenvalues. Filled by
- * compute_eigenvalues.
+ * Imaginary parts of eigenvalues. Filled by compute_eigenvalues.
*/
std::vector<number> wi;
/**
- * Space where left eigenvectors
- * can be stored.
+ * Space where left eigenvectors can be stored.
*/
std::vector<number> vl;
/**
- * Space where right eigenvectors
- * can be stored.
+ * Space where right eigenvectors can be stored.
*/
std::vector<number> vr;
/**
- * The matrix <i>U</i> in the
- * singular value decomposition
+ * The matrix <i>U</i> in the singular value decomposition
* <i>USV<sup>T</sup></i>.
*/
std_cxx1x::shared_ptr<LAPACKFullMatrix<number> > svd_u;
+
/**
- * The matrix
- * <i>V<sup>T</sup></i> in the
- * singular value decomposition
+ * The matrix <i>V<sup>T</sup></i> in the singular value decomposition
* <i>USV<sup>T</sup></i>.
*/
std_cxx1x::shared_ptr<LAPACKFullMatrix<number> > svd_vt;
{
template <class MATRIX>
void
- reinit(MatrixBlock<MATRIX> &v, const BlockSparsityPattern &p);
+ reinit(MatrixBlock<MATRIX> &v,
+ const BlockSparsityPattern &p);
template <typename number>
void
- reinit(MatrixBlock<dealii::SparseMatrix<number> > &, const BlockSparsityPattern &);
+ reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+ const BlockSparsityPattern &p);
}
/**
* The matrix itself
*/
MATRIX matrix;
+
private:
/**
* The rwo BlockIndices of the
BlockIndices column_indices;
template <class OTHER_MATRIX>
- friend void internal::reinit(MatrixBlock<OTHER_MATRIX> &, const BlockSparsityPattern &);
+ friend
+ void dealii::internal::reinit(MatrixBlock<OTHER_MATRIX> &,
+ const BlockSparsityPattern &);
+
+ template <typename number>
+ friend
+ void internal::reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+ const BlockSparsityPattern &p);
};
{
template <class MATRIX>
void
- reinit(MatrixBlock<MATRIX> &v, const BlockSparsityPattern &p)
+ reinit(MatrixBlock<MATRIX> &v,
+ const BlockSparsityPattern &p)
{
v.row_indices = p.get_row_indices();
v.column_indices = p.get_column_indices();
template <typename number>
void
- reinit(MatrixBlock<dealii::SparseMatrix<number> > &v, const BlockSparsityPattern &p)
+ reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+ const BlockSparsityPattern &p)
{
v.row_indices = p.get_row_indices();
v.column_indices = p.get_column_indices();
fe_eval.template apply_gradients<0,false,false>
(fe_eval.gradients_quad[c][0], temp1);
}
- fe_eval.template apply_values<1,false,false>
- (temp1, temp2);
+ if (integrate_val || integrate_grad)
+ fe_eval.template apply_values<1,false,false>
+ (temp1, temp2);
if (integrate_grad == true)
{
// grad y: can sum to temporary x value in temp2
fe_eval.template apply_gradients<1,false,true>
(temp1, temp2);
}
- fe_eval.template apply_values<2,false,false>
- (temp2, fe_eval.values_dofs[c]);
+ if (integrate_val || integrate_grad)
+ fe_eval.template apply_values<2,false,false>
+ (temp2, fe_eval.values_dofs[c]);
if (integrate_grad == true)
{
// grad z: can sum to temporary x and y value in output
fe_eval.template apply_gradients<0,false,false>
(fe_eval.gradients_quad[c][0], temp1);
}
- fe_eval.template apply_values<1,false,false>
- (temp1, fe_eval.values_dofs[c]);
+ if (integrate_val || integrate_grad)
+ fe_eval.template apply_values<1,false,false>
+ (temp1, fe_eval.values_dofs[c]);
if (integrate_grad == true)
{
// grad y
*/
static const unsigned int n_cell_types = 1U<<n_cell_type_bits;
+ /**
+ * An abbreviation for the length of vector lines of the current data type.
+ */
+ static const unsigned int n_vector_elements = VectorizedArray<Number>::n_array_elements;
+
/**
* Empty constructor.
*/
/**
* Contains all the stuff that depends on the quadrature formula
-
*/
std::vector<MappingInfoDependent> mapping_data_gen;
const std::pair<unsigned int,unsigned int> *cells,
const unsigned int cell,
const unsigned int my_q,
- CellType (&cell_t_prev)[VectorizedArray<Number>::n_array_elements],
- CellType (&cell_t)[VectorizedArray<Number>::n_array_elements],
+ CellType (&cell_t_prev)[n_vector_elements],
+ CellType (&cell_t)[n_vector_elements],
FEValues<dim,dim> &fe_values,
CellData &cell_data) const;
};
const std::pair<unsigned int,unsigned int> *cells,
const unsigned int cell,
const unsigned int my_q,
- CellType (&cell_t_prev)[VectorizedArray<Number>::n_array_elements],
- CellType (&cell_t)[VectorizedArray<Number>::n_array_elements],
+ CellType (&cell_t_prev)[n_vector_elements],
+ CellType (&cell_t)[n_vector_elements],
FEValues<dim,dim> &fe_val,
CellData &data) const
{
- const unsigned int vectorization_length =
- VectorizedArray<Number>::n_array_elements;
const unsigned int n_q_points = fe_val.n_quadrature_points;
const UpdateFlags update_flags = fe_val.get_update_flags();
// not have that field here)
const double zero_tolerance_double = data.jac_size *
std::numeric_limits<double>::epsilon() * 1024.;
- for (unsigned int j=0; j<vectorization_length; ++j)
+ for (unsigned int j=0; j<n_vector_elements; ++j)
{
typename dealii::Triangulation<dim>::cell_iterator
cell_it (&tria, cells[j].first, cells[j].second);
if (j==0)
{
Assert (cell>0, ExcInternalError());
- cell_t[j] = cell_t_prev[vectorization_length-1];
+ cell_t[j] = cell_t_prev[n_vector_elements-1];
}
else
cell_t[j] = cell_t[j-1];
data.general_jac_grad[q][d][e][f][j] = jacobian_grad[d][e][f];
}
}
- } // end loop over all entries in vectorization (vectorization_length
+ } // end loop over all entries in vectorization (n_vector_elements
// cells)
// set information for next cell
- for (unsigned int j=0; j<vectorization_length; ++j)
+ for (unsigned int j=0; j<n_vector_elements; ++j)
cell_t_prev[j] = cell_t[j];
}
*/
MGTransferPrebuilt ();
/**
- * Constructor with constraint matrices as well as mg_constrained_dofs.
+ * Constructor with constraints. Equivalent to the default
+ * constructor followed by initialize_constraints().
*/
MGTransferPrebuilt (const ConstraintMatrix &constraints,
const MGConstrainedDoFs &mg_constrained_dofs);
* Destructor.
*/
virtual ~MGTransferPrebuilt ();
+
+ /**
+ * Initialize the constraints to be used in build_matrices().
+ */
+ void initialize_constraints (const ConstraintMatrix &constraints,
+ const MGConstrainedDoFs &mg_constrained_dofs);
+
+ /**
+ * Reset the object to the state it had right after the default constructor.
+ */
+ void clear ();
+
/**
* Actually build the prolongation
* matrices for each level.
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1999 - 2013 by the deal.II authors
+// Copyright (C) 1999 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
* this pair of functions and they return a non-active cell, then an exception
* will be thrown.
*
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
* @ingroup output
* @author Wolfgang Bangerth, 1999
*/
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
* applications certainly exist, for which the author is not
* imaginative enough.
*
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
* @todo Reimplement this whole class using actual FEFaceValues and MeshWorker.
*
* @ingroup output
DH::dimension>
{
public:
+ /**
+ * An abbreviation for the dimension of the DoFHandler object we work
+ * with. Faces are then <code>dimension-1</code> dimensional objects.
+ */
+ static const unsigned int dimension = DH::dimension;
+
+ /**
+ * An abbreviation for the spatial dimension within which the triangulation
+ * and DoFHandler are embedded in.
+ */
+ static const unsigned int space_dimension = DH::space_dimension;
+
/**
* Typedef to the iterator type
* of the dof handler class under
* consideration.
*/
- typedef typename DataOut_DoFData<DH,DH::dimension-1,
- DH::dimension>::cell_iterator cell_iterator;
+ typedef typename DataOut_DoFData<DH,dimension-1,
+ dimension>::cell_iterator cell_iterator;
/**
* Constructor determining
* replaced by a hp::MappingCollection in
* case of a hp::DoFHandler.
*/
- virtual void build_patches (const Mapping<DH::dimension> &mapping,
+ virtual void build_patches (const Mapping<dimension> &mapping,
const unsigned int n_subdivisions = 0);
/**
* context.
*/
void build_one_patch (const FaceDescriptor *cell_and_face,
- internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
- DataOutBase::Patch<DH::dimension-1,DH::space_dimension> &patch);
+ internal::DataOutFaces::ParallelData<dimension, dimension> &data,
+ DataOutBase::Patch<dimension-1,space_dimension> &patch);
};
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
* It is in the responsibility of the user to make sure that the
* radial variable attains only non-negative values.
*
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
* @ingroup output
* @author Wolfgang Bangerth, 2000
*/
class DataOutRotation : public DataOut_DoFData<DH,DH::dimension+1>
{
public:
+ /**
+ * An abbreviation for the dimension of the DoFHandler object we work
+ * with. Faces are then <code>dimension-1</code> dimensional objects.
+ */
+ static const unsigned int dimension = DH::dimension;
+
+ /**
+ * An abbreviation for the spatial dimension within which the triangulation
+ * and DoFHandler are embedded in.
+ */
+ static const unsigned int space_dimension = DH::space_dimension;
+
/**
* Typedef to the iterator type
* of the dof handler class under
* consideration.
*/
- typedef typename DataOut_DoFData<DH,DH::dimension+1>::cell_iterator cell_iterator;
+ typedef typename DataOut_DoFData<DH,dimension+1>::cell_iterator cell_iterator;
/**
* This is the central function
*/
void
build_one_patch (const cell_iterator *cell,
- internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
- std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches);
+ internal::DataOutRotation::ParallelData<dimension, space_dimension> &data,
+ std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> > &patches);
};
/**
- * This class computes a cell-wise approximation of the norm of a
+ * This namespace provides functions that compute a cell-wise approximation of the norm of a
* derivative of a finite element field by taking difference quotients
* between neighboring cells. This is a rather simple but efficient
* form to get an error indicator, since it can be computed with
* @code
* --------------------------------------------------------
* An error occurred in line <749> of file <source/numerics/derivative_approximation.cc> in function
- * static void DerivativeApproximation::approximate(const Mapping<dim,spacedim>&, const DH<dim,spacedim>&, const InputVector&, unsigned int, const
+ * void DerivativeApproximation::approximate(const Mapping<dim,spacedim>&, const DH<dim,spacedim>&, const InputVector&, unsigned int, const
* std::pair<unsigned int, unsigned int>&, Vector<float>&) [with DerivativeDescription = DerivativeApproximation::Gradient<3>, int
* dim = 3, DH = DoFHandler, InputVector = Vector<double>]
* The violated condition was:
* The formulae for the computation of approximations to the gradient
* and to the tensor of second derivatives shown above are very much
* alike. The basic difference is that in one case the finite
- * difference quotiont is a scalar, while in the other case it is a
+ * difference quotient is a scalar, while in the other case it is a
* vector. For higher derivatives, this would be a tensor of even
* higher rank. We then have to form the outer product of this
* difference quotient with the distance vector $y_{KK'}$, symmetrize
* @ingroup numerics
* @author Wolfgang Bangerth, 2000
*/
-class DerivativeApproximation
+namespace DerivativeApproximation
{
-public:
/**
* This function is used to obtain an approximation of the gradient. Pass it
* the DoF handler object that describes the finite element field, a nodal
* locally relevant unknowns.
*/
template <int dim, template <int, int> class DH, class InputVector, int spacedim>
- static void
+ void
approximate_gradient (const Mapping<dim,spacedim> &mapping,
const DH<dim,spacedim> &dof,
const InputVector &solution,
* <tt>mapping=MappingQ1@<dim@>()</tt>.
*/
template <int dim, template <int, int> class DH, class InputVector, int spacedim>
- static void
+ void
approximate_gradient (const DH<dim,spacedim> &dof,
const InputVector &solution,
Vector<float> &derivative_norm,
* locally relevant unknowns.
*/
template <int dim, template <int, int> class DH, class InputVector, int spacedim>
- static void
+ void
approximate_second_derivative (const Mapping<dim,spacedim> &mapping,
const DH<dim,spacedim> &dof,
const InputVector &solution,
* <tt>mapping=MappingQ1@<dim@>()</tt>.
*/
template <int dim, template <int, int> class DH, class InputVector, int spacedim>
- static void
+ void
approximate_second_derivative (const DH<dim,spacedim> &dof,
const InputVector &solution,
Vector<float> &derivative_norm,
* In a parallel computation the @p solution vector needs to contain the
* locally relevant unknowns.
*/
-
template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
- static void
+ void
approximate_derivative_tensor (const Mapping<dim,spacedim> &mapping,
const DH<dim,spacedim> &dof,
const InputVector &solution,
/**
* Same as above, with <tt>mapping=MappingQ1@<dim@>()</tt>.
*/
-
template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
- static void
+ void
approximate_derivative_tensor (const DH<dim,spacedim> &dof,
const InputVector &solution,
const typename DH<dim,spacedim>::active_cell_iterator &cell,
* Return the norm of the derivative.
*/
template <int dim, int order>
- static double
- derivative_norm(const Tensor<order,dim> &derivative);
+ double
+ derivative_norm (const Tensor<order,dim> &derivative);
/**
* Exception
* Exception
*/
DeclException0 (ExcInsufficientDirections);
+}
-private:
-
- /**
- * The following class is used to describe the data needed to compute the
- * finite difference approximation to the gradient on a cell. See the
- * general documentation of this class for more information on
- * implementational details.
- *
- * @author Wolfgang Bangerth, 2000
- */
- template <int dim>
- class Gradient
- {
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which holds the derivative described by this
- * class.
- */
- typedef Tensor<1,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef double ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the gradient, we
- * choose the Euclidian norm of the gradient vector.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the first derivatives, no such thing is necessary, so this function
- * is a no-op.
- */
- static void symmetrize (Derivative &derivative_tensor);
- };
-
-
-
- /**
- * The following class is used to describe the data needed to compute the
- * finite difference approximation to the second derivatives on a cell. See
- * the general documentation of this class for more information on
- * implementational details.
- *
- * @author Wolfgang Bangerth, 2000
- */
- template <int dim>
- class SecondDerivative
- {
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which holds the derivative described by this
- * class.
- */
- typedef Tensor<2,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef Tensor<1,dim> ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the (symmetric)
- * tensor of second derivatives, we choose the absolute value of the
- * largest eigenvalue, which is the matrix norm associated to the $l_2$
- * norm of vectors. It is also the largest value of the curvature of the
- * solution.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the second derivatives, each entry of the tensor is set to the mean
- * of its value and the value of the transpose element.
- *
- * Note that this function actually modifies its argument.
- */
- static void symmetrize (Derivative &derivative_tensor);
- };
-
- template <int dim>
- class ThirdDerivative
- {
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which
- * holds the derivative described
- * by this class.
- */
- typedef Tensor<3,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef Tensor<2,dim> ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the (symmetric)
- * tensor of second derivatives, we choose the absolute value of the
- * largest eigenvalue, which is the matrix norm associated to the $l_2$
- * norm of vectors. It is also the largest value of the curvature of the
- * solution.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the second derivatives, each entry of the tensor is set to the mean
- * of its value and the value of the transpose element.
- *
- * Note that this function actually modifies its argument.
- */
- static void symmetrize (Derivative &derivative_tensor);
- };
-
- template <int order, int dim>
- class DerivativeSelector
- {
- public:
- /**
- * typedef to select the DerivativeDescription corresponding to the
- * <tt>order</tt>th derivative. In this general template we set an unvalid
- * typedef to void, the real typedefs have to be specialized.
- */
- typedef void DerivDescr;
-
- };
-
- template <int dim>
- class DerivativeSelector<1,dim>
- {
- public:
-
- typedef Gradient<dim> DerivDescr;
- };
-
- template <int dim>
- class DerivativeSelector<2,dim>
- {
- public:
-
- typedef SecondDerivative<dim> DerivDescr;
- };
-
- template <int dim>
- class DerivativeSelector<3,dim>
- {
- public:
-
- typedef ThirdDerivative<dim> DerivDescr;
- };
-
-
-
-
-private:
-
- /**
- * Convenience typedef denoting the range of indices on which a certain
- * thread shall operate.
- */
- typedef std::pair<unsigned int,unsigned int> IndexInterval;
-
- /**
- * Kind of the main function of this class. It is called by the public entry
- * points to this class with the correct template first argument and then
- * simply calls the @p approximate function, after setting up several
- * threads and doing some administration that is independent of the actual
- * derivative to be computed.
- *
- * The @p component argument denotes which component of the solution vector
- * we are to work on.
- */
- template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
- static void
- approximate_derivative (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const unsigned int component,
- Vector<float> &derivative_norm);
-
- /**
- * Compute the derivative approximation on a given cell. Fill the @p
- * derivative_norm vector with the norm of the computed derivative tensors
- * on the cell.
- */
- template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
- static void
- approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,
- Vector<float>::iterator> > const &cell,
- const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Compute the derivative approximation on one cell. This computes the full
- * derivative tensor.
- */
- template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
- static void
- approximate_cell (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const unsigned int component,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- typename DerivativeDescription::Derivative &derivative);
-};
-
-
-/* -------------- declaration of explicit specializations ------------- */
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<1>::derivative_norm (const Derivative &d);
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<2>::derivative_norm (const Derivative &d);
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<3>::derivative_norm (const Derivative &d);
DEAL_II_NAMESPACE_CLOSE
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
+ // template for the case dim!=1. Since the function has a template argument
+ // dim_, it is clearly less specialized than the 1d function above and
+ // whenever possible (i.e., if dim==1), the function template above
+ // will be used
template <class DH,
- template <int,int> class M_or_MC>
+ template <int,int> class M_or_MC,
+ int dim_>
static inline
void
do_interpolate_boundary_values (const M_or_MC<DH::dimension, DH::space_dimension> &mapping,
const typename FunctionMap<DH::space_dimension>::type &function_map,
std::map<types::global_dof_index,double> &boundary_values,
const ComponentMask &component_mask,
- const dealii::internal::int2type<DH::dimension>)
+ const dealii::internal::int2type<dim_>)
{
const unsigned int dim = DH::dimension;
const unsigned int spacedim=DH::space_dimension;
#
INCLUDE_DIRECTORIES(
- BEFORE # Ensure deal.II include directories come first
- #
- # Reverse order due to BEFORE:
- #
- ${CMAKE_SOURCE_DIR}/include/
${CMAKE_BINARY_DIR}/include/
+ ${CMAKE_SOURCE_DIR}/include/
+ ${DEAL_II_BUNDLED_INCLUDE_DIRS}
+ ${DEAL_II_INCLUDE_DIRS}
)
#
)
TARGET_LINK_LIBRARIES(${DEAL_II_BASE_NAME}${DEAL_II_${build}_SUFFIX}
- ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
- ${DEAL_II_EXTERNAL_LIBRARIES}
+ ${DEAL_II_LIBRARIES_${build}}
+ ${DEAL_II_LIBRARIES}
)
FILE(MAKE_DIRECTORY
#endif
}
+
+// some declarations of functions and locally used classes
+namespace DataOutBase
+{
+ namespace
+ {
+ /**
+ * Class holding the data of one cell of a patch in two space
+ * dimensions for output. It is the projection of a cell in
+ * three-dimensional space (two coordinates, one height value) to
+ * the direction of sight.
+ */
+ class SvgCell
+ {
+ public:
+
+ // Center of the cell (three-dimensional)
+ Point<3> center;
+
+ /**
+ * Vector of vertices of this cell (three-dimensional)
+ */
+ Point<3> vertices[4];
+
+ /**
+ * Depth into the picture, which is defined as the distance from
+ * an observer at an the origin in direction of the line of sight.
+ */
+ float depth;
+
+ /**
+ * Vector of vertices of this cell (projected, two-dimensional).
+ */
+ Point<2> projected_vertices[4];
+
+ // Center of the cell (projected, two-dimensional)
+ Point<2> projected_center;
+
+ /**
+ * Comparison operator for sorting.
+ */
+ bool operator < (const SvgCell &) const;
+ };
+
+ bool SvgCell::operator < (const SvgCell &e) const
+ {
+ // note the "wrong" order in
+ // which we sort the elements
+ return depth > e.depth;
+ }
+
+
+
+ /**
+ * Class holding the data of one cell of a patch in two space
+ * dimensions for output. It is the projection of a cell in
+ * three-dimensional space (two coordinates, one height value) to
+ * the direction of sight.
+ */
+ class EpsCell2d
+ {
+ public:
+
+ /**
+ * Vector of vertices of this cell.
+ */
+ Point<2> vertices[4];
+
+ /**
+ * Data value from which the actual colors will be computed by the
+ * colorization function stated in the <tt>EpsFlags</tt> class.
+ */
+ float color_value;
+
+ /**
+ * Depth into the picture, which is defined as the distance from
+ * an observer at an the origin in direction of the line of sight.
+ */
+ float depth;
+
+ /**
+ * Comparison operator for sorting.
+ */
+ bool operator < (const EpsCell2d &) const;
+ };
+
+
+ /**
+ * This is a helper function for the write_gmv() function. There,
+ * the data in the patches needs to be copied around as output is
+ * one variable globally at a time, rather than all data on each
+ * vertex at a time. This copying around can be done detached from
+ * the main thread, and is thus moved into this separate function.
+ *
+ * Note that because of the similarity of the formats, this function
+ * is also used by the Vtk and Tecplot output functions.
+ */
+ template <int dim, int spacedim>
+ void
+ write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
+ Table<2,double> &data_vectors)
+ {
+ // unlike in the main function, we
+ // don't have here the data_names
+ // field, so we initialize it with
+ // the number of data sets in the
+ // first patch. the equivalence of
+ // these two definitions is checked
+ // in the main function.
+
+ // we have to take care, however, whether the
+ // points are appended to the end of the
+ // patch->data table
+ const unsigned int n_data_sets
+ =patches[0].points_are_available ? (patches[0].data.n_rows() - spacedim) : patches[0].data.n_rows();
+
+ Assert (data_vectors.size()[0] == n_data_sets,
+ ExcInternalError());
+
+ // loop over all patches
+ unsigned int next_value = 0;
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch != patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+
+ Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
+ Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+ for (unsigned int i=0; i<patch->data.n_cols(); ++i, ++next_value)
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ data_vectors[data_set][next_value] = patch->data(data_set,i);
+ }
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ Assert (data_vectors[data_set].size() == next_value,
+ ExcInternalError());
+ }
+ }
+}
+
//----------------------------------------------------------------------//
// DataOutFilter class member functions
//----------------------------------------------------------------------//
namespace
{
-
- static const char *gmv_cell_type[4] =
+ const char *gmv_cell_type[4] =
{
"", "line 2", "quad 4", "hex 8"
};
- static const char *ucd_cell_type[4] =
+ const char *ucd_cell_type[4] =
{
"", "line", "quad", "hex"
};
- static const char *tecplot_cell_type[4] =
+ const char *tecplot_cell_type[4] =
{
"", "lineseg", "quadrilateral", "brick"
};
#ifdef DEAL_II_HAVE_TECPLOT
- static unsigned int tecplot_binary_cell_type[4] =
+ const unsigned int tecplot_binary_cell_type[4] =
{
0, 0, 1, 3
};
#endif
- // NOTE: (UK) The dimension of the array is choosen to 5 to allow the choice
+ // NOTE: The dimension of the array is choosen to 5 to allow the choice
// DataOutBase<deal_II_dimension,deal_II_dimension+1> in general
// Wolfgang supposed that we don't need it in general, but however this
// choice avoids a -Warray-bounds check warning
- static unsigned int vtk_cell_type[5] =
+ const unsigned int vtk_cell_type[5] =
{
0, 3, 9, 12, static_cast<unsigned int>(-1)
};
//----------------------------------------------------------------------//
-template <int dim, int spacedim>
-const unsigned int DataOutBase::Patch<dim,spacedim>::space_dim;
-const unsigned int DataOutBase::Deal_II_IntermediateFlags::format_version;
+namespace DataOutBase
+{
+ template <int dim, int spacedim>
+ const unsigned int Patch<dim,spacedim>::space_dim;
+
+ const unsigned int Deal_II_IntermediateFlags::format_version;
-template <int dim, int spacedim>
-const unsigned int DataOutBase::Patch<dim,spacedim>::no_neighbor;
+ template <int dim, int spacedim>
+ const unsigned int Patch<dim,spacedim>::no_neighbor;
-template <int dim, int spacedim>
-DataOutBase::Patch<dim,spacedim>::Patch ()
- :
- patch_index(no_neighbor),
- n_subdivisions (1),
- points_are_available(false)
- // all the other data has a
- // constructor of its own, except
- // for the "neighbors" field, which
- // we set to invalid values.
-{
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- neighbors[i] = no_neighbor;
+ template <int dim, int spacedim>
+ Patch<dim,spacedim>::Patch ()
+ :
+ patch_index(no_neighbor),
+ n_subdivisions (1),
+ points_are_available(false)
+ // all the other data has a
+ // constructor of its own, except
+ // for the "neighbors" field, which
+ // we set to invalid values.
+ {
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ neighbors[i] = no_neighbor;
- Assert (dim<=spacedim, ExcIndexRange(dim,0,spacedim));
- Assert (spacedim<=3, ExcNotImplemented());
-}
+ Assert (dim<=spacedim, ExcIndexRange(dim,0,spacedim));
+ Assert (spacedim<=3, ExcNotImplemented());
+ }
-template <int dim, int spacedim>
-bool
-DataOutBase::Patch<dim,spacedim>::operator == (const Patch &patch) const
-{
+ template <int dim, int spacedim>
+ bool
+ Patch<dim,spacedim>::operator == (const Patch &patch) const
+ {
//TODO: make tolerance relative
- const double epsilon=3e-16;
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- if (vertices[i].distance(patch.vertices[i]) > epsilon)
- return false;
+ const double epsilon=3e-16;
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ if (vertices[i].distance(patch.vertices[i]) > epsilon)
+ return false;
+
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ if (neighbors[i] != patch.neighbors[i])
+ return false;
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- if (neighbors[i] != patch.neighbors[i])
+ if (patch_index != patch.patch_index)
return false;
- if (patch_index != patch.patch_index)
- return false;
+ if (n_subdivisions != patch.n_subdivisions)
+ return false;
- if (n_subdivisions != patch.n_subdivisions)
- return false;
+ if (points_are_available != patch.points_are_available)
+ return false;
- if (points_are_available != patch.points_are_available)
- return false;
+ if (data.n_rows() != patch.data.n_rows())
+ return false;
- if (data.n_rows() != patch.data.n_rows())
- return false;
+ if (data.n_cols() != patch.data.n_cols())
+ return false;
- if (data.n_cols() != patch.data.n_cols())
- return false;
+ for (unsigned int i=0; i<data.n_rows(); ++i)
+ for (unsigned int j=0; j<data.n_cols(); ++j)
+ if (data[i][j] != patch.data[i][j])
+ return false;
- for (unsigned int i=0; i<data.n_rows(); ++i)
- for (unsigned int j=0; j<data.n_cols(); ++j)
- if (data[i][j] != patch.data[i][j])
- return false;
+ return true;
+ }
- return true;
-}
+ template <int dim, int spacedim>
+ std::size_t
+ Patch<dim,spacedim>::memory_consumption () const
+ {
+ return (sizeof(vertices) / sizeof(vertices[0]) *
+ MemoryConsumption::memory_consumption(vertices[0])
+ +
+ MemoryConsumption::memory_consumption(n_subdivisions)
+ +
+ MemoryConsumption::memory_consumption(data)
+ +
+ MemoryConsumption::memory_consumption(points_are_available));
+ }
-template <int dim, int spacedim>
-std::size_t
-DataOutBase::Patch<dim,spacedim>::memory_consumption () const
-{
- return (sizeof(vertices) / sizeof(vertices[0]) *
- MemoryConsumption::memory_consumption(vertices[0])
- +
- MemoryConsumption::memory_consumption(n_subdivisions)
- +
- MemoryConsumption::memory_consumption(data)
- +
- MemoryConsumption::memory_consumption(points_are_available));
-}
+ UcdFlags::UcdFlags (const bool write_preamble)
+ :
+ write_preamble (write_preamble)
+ {}
-DataOutBase::UcdFlags::UcdFlags (const bool write_preamble)
- :
- write_preamble (write_preamble)
-{}
+ PovrayFlags::PovrayFlags (const bool smooth,
+ const bool bicubic_patch,
+ const bool external_data)
+ :
+ smooth (smooth),
+ bicubic_patch(bicubic_patch),
+ external_data(external_data)
+ {}
-DataOutBase::PovrayFlags::PovrayFlags (const bool smooth,
- const bool bicubic_patch,
- const bool external_data)
- :
- smooth (smooth),
- bicubic_patch(bicubic_patch),
- external_data(external_data)
-{}
+ DataOutFilterFlags::DataOutFilterFlags (const bool filter_duplicate_vertices,
+ const bool xdmf_hdf5_output) :
+ filter_duplicate_vertices(filter_duplicate_vertices),
+ xdmf_hdf5_output(xdmf_hdf5_output)
+ {}
-DataOutBase::DataOutFilterFlags::DataOutFilterFlags (const bool filter_duplicate_vertices,
- const bool xdmf_hdf5_output) :
- filter_duplicate_vertices(filter_duplicate_vertices),
- xdmf_hdf5_output(xdmf_hdf5_output) {}
-void DataOutBase::DataOutFilterFlags::declare_parameters (ParameterHandler &prm)
-{
- prm.declare_entry ("Filter duplicate vertices", "false",
- Patterns::Bool(),
- "Whether to remove duplicate vertex values.");
- prm.declare_entry ("XDMF HDF5 output", "false",
- Patterns::Bool(),
- "Whether the data will be used in an XDMF/HDF5 combination.");
-}
+ void DataOutFilterFlags::declare_parameters (ParameterHandler &prm)
+ {
+ prm.declare_entry ("Filter duplicate vertices", "false",
+ Patterns::Bool(),
+ "Whether to remove duplicate vertex values.");
+ prm.declare_entry ("XDMF HDF5 output", "false",
+ Patterns::Bool(),
+ "Whether the data will be used in an XDMF/HDF5 combination.");
+ }
-void DataOutBase::DataOutFilterFlags::parse_parameters (const ParameterHandler &prm)
-{
- filter_duplicate_vertices = prm.get_bool ("Filter duplicate vertices");
- xdmf_hdf5_output = prm.get_bool ("XDMF HDF5 output");
-}
+ void DataOutFilterFlags::parse_parameters (const ParameterHandler &prm)
+ {
+ filter_duplicate_vertices = prm.get_bool ("Filter duplicate vertices");
+ xdmf_hdf5_output = prm.get_bool ("XDMF HDF5 output");
+ }
-std::size_t
-DataOutBase::DataOutFilterFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ DataOutFilterFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::DXFlags::DXFlags (const bool write_neighbors,
- const bool int_binary,
- const bool coordinates_binary,
- const bool data_binary)
- :
- write_neighbors(write_neighbors),
- int_binary(int_binary),
- coordinates_binary(coordinates_binary),
- data_binary(data_binary),
- data_double(false)
-{}
+ DXFlags::DXFlags (const bool write_neighbors,
+ const bool int_binary,
+ const bool coordinates_binary,
+ const bool data_binary)
+ :
+ write_neighbors(write_neighbors),
+ int_binary(int_binary),
+ coordinates_binary(coordinates_binary),
+ data_binary(data_binary),
+ data_double(false)
+ {}
-void DataOutBase::DXFlags::declare_parameters (ParameterHandler &prm)
-{
- prm.declare_entry ("Write neighbors", "true",
- Patterns::Bool(),
- "A boolean field indicating whether neighborship "
- "information between cells is to be written to the "
- "OpenDX output file");
- prm.declare_entry ("Integer format", "ascii",
- Patterns::Selection("ascii|32|64"),
- "Output format of integer numbers, which is "
- "either a text representation (ascii) or binary integer "
- "values of 32 or 64 bits length");
- prm.declare_entry ("Coordinates format", "ascii",
- Patterns::Selection("ascii|32|64"),
- "Output format of vertex coordinates, which is "
- "either a text representation (ascii) or binary "
- "floating point values of 32 or 64 bits length");
- prm.declare_entry ("Data format", "ascii",
- Patterns::Selection("ascii|32|64"),
- "Output format of data values, which is "
- "either a text representation (ascii) or binary "
- "floating point values of 32 or 64 bits length");
-}
+ void DXFlags::declare_parameters (ParameterHandler &prm)
+ {
+ prm.declare_entry ("Write neighbors", "true",
+ Patterns::Bool(),
+ "A boolean field indicating whether neighborship "
+ "information between cells is to be written to the "
+ "OpenDX output file");
+ prm.declare_entry ("Integer format", "ascii",
+ Patterns::Selection("ascii|32|64"),
+ "Output format of integer numbers, which is "
+ "either a text representation (ascii) or binary integer "
+ "values of 32 or 64 bits length");
+ prm.declare_entry ("Coordinates format", "ascii",
+ Patterns::Selection("ascii|32|64"),
+ "Output format of vertex coordinates, which is "
+ "either a text representation (ascii) or binary "
+ "floating point values of 32 or 64 bits length");
+ prm.declare_entry ("Data format", "ascii",
+ Patterns::Selection("ascii|32|64"),
+ "Output format of data values, which is "
+ "either a text representation (ascii) or binary "
+ "floating point values of 32 or 64 bits length");
+ }
-void DataOutBase::DXFlags::parse_parameters (const ParameterHandler &prm)
-{
- write_neighbors = prm.get_bool ("Write neighbors");
+ void DXFlags::parse_parameters (const ParameterHandler &prm)
+ {
+ write_neighbors = prm.get_bool ("Write neighbors");
//TODO:[GK] Read the new parameters
-}
+ }
-std::size_t
-DataOutBase::DXFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ DXFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-void DataOutBase::UcdFlags::declare_parameters (ParameterHandler &prm)
-{
- prm.declare_entry ("Write preamble", "true",
- Patterns::Bool(),
- "A flag indicating whether a comment should be "
- "written to the beginning of the output file "
- "indicating date and time of creation as well "
- "as the creating program");
-}
+ void UcdFlags::declare_parameters (ParameterHandler &prm)
+ {
+ prm.declare_entry ("Write preamble", "true",
+ Patterns::Bool(),
+ "A flag indicating whether a comment should be "
+ "written to the beginning of the output file "
+ "indicating date and time of creation as well "
+ "as the creating program");
+ }
-void DataOutBase::UcdFlags::parse_parameters (const ParameterHandler &prm)
-{
- write_preamble = prm.get_bool ("Write preamble");
-}
+ void UcdFlags::parse_parameters (const ParameterHandler &prm)
+ {
+ write_preamble = prm.get_bool ("Write preamble");
+ }
-std::size_t
-DataOutBase::UcdFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ UcdFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::GnuplotFlags::GnuplotFlags ()
- :
- dummy (0)
-{}
+ GnuplotFlags::GnuplotFlags ()
+ :
+ dummy (0)
+ {}
-void DataOutBase::GnuplotFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+ void GnuplotFlags::declare_parameters (ParameterHandler &/*prm*/)
+ {}
-void DataOutBase::GnuplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+ void GnuplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+ {}
-size_t
-DataOutBase::GnuplotFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ size_t
+ GnuplotFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-std::size_t
-DataOutBase::SvgFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ SvgFlags::SvgFlags (const unsigned int height_vector,
+ const int azimuth_angle,
+ const int polar_angle,
+ const unsigned int line_thickness,
+ const bool margin,
+ const bool draw_colorbar)
+ :
+ height(4000),
+ width(0),
+ height_vector(height_vector),
+ azimuth_angle(azimuth_angle),
+ polar_angle(polar_angle),
+ line_thickness(line_thickness),
+ margin(margin),
+ draw_colorbar(draw_colorbar)
+ {}
+ std::size_t
+ SvgFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
+
-void DataOutBase::PovrayFlags::declare_parameters (ParameterHandler &prm)
-{
- prm.declare_entry ("Use smooth triangles", "false",
- Patterns::Bool(),
- "A flag indicating whether POVRAY should use smoothed "
- "triangles instead of the usual ones");
- prm.declare_entry ("Use bicubic patches", "false",
- Patterns::Bool(),
- "Whether POVRAY should use bicubic patches");
- prm.declare_entry ("Include external file", "true",
- Patterns::Bool (),
- "Whether camera and lightling information should "
- "be put into an external file \"data.inc\" or into "
- "the POVRAY input file");
-}
+ void PovrayFlags::declare_parameters (ParameterHandler &prm)
+ {
+ prm.declare_entry ("Use smooth triangles", "false",
+ Patterns::Bool(),
+ "A flag indicating whether POVRAY should use smoothed "
+ "triangles instead of the usual ones");
+ prm.declare_entry ("Use bicubic patches", "false",
+ Patterns::Bool(),
+ "Whether POVRAY should use bicubic patches");
+ prm.declare_entry ("Include external file", "true",
+ Patterns::Bool (),
+ "Whether camera and lightling information should "
+ "be put into an external file \"data.inc\" or into "
+ "the POVRAY input file");
+ }
-void DataOutBase::PovrayFlags::parse_parameters (const ParameterHandler &prm)
-{
- smooth = prm.get_bool ("Use smooth triangles");
- bicubic_patch = prm.get_bool ("Use bicubic patches");
- external_data = prm.get_bool ("Include external file");
-}
+ void PovrayFlags::parse_parameters (const ParameterHandler &prm)
+ {
+ smooth = prm.get_bool ("Use smooth triangles");
+ bicubic_patch = prm.get_bool ("Use bicubic patches");
+ external_data = prm.get_bool ("Include external file");
+ }
-std::size_t
-DataOutBase::PovrayFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ PovrayFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::EpsFlags::EpsFlags (const unsigned int height_vector,
- const unsigned int color_vector,
- const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const double azimut_angle,
- const double turn_angle,
- const double z_scaling,
- const bool draw_mesh,
- const bool draw_cells,
- const bool shade_cells,
- const ColorFunction color_function)
- :
- height_vector(height_vector),
- color_vector(color_vector),
- size_type(size_type),
- size(size),
- line_width(line_width),
- azimut_angle(azimut_angle),
- turn_angle(turn_angle),
- z_scaling(z_scaling),
- draw_mesh(draw_mesh),
- draw_cells(draw_cells),
- shade_cells(shade_cells),
- color_function(color_function)
-{}
+ EpsFlags::EpsFlags (const unsigned int height_vector,
+ const unsigned int color_vector,
+ const SizeType size_type,
+ const unsigned int size,
+ const double line_width,
+ const double azimut_angle,
+ const double turn_angle,
+ const double z_scaling,
+ const bool draw_mesh,
+ const bool draw_cells,
+ const bool shade_cells,
+ const ColorFunction color_function)
+ :
+ height_vector(height_vector),
+ color_vector(color_vector),
+ size_type(size_type),
+ size(size),
+ line_width(line_width),
+ azimut_angle(azimut_angle),
+ turn_angle(turn_angle),
+ z_scaling(z_scaling),
+ draw_mesh(draw_mesh),
+ draw_cells(draw_cells),
+ shade_cells(shade_cells),
+ color_function(color_function)
+ {}
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::default_color_function (const double x,
- const double xmin,
- const double xmax)
-{
- RgbValues rgb_values = { 0,0,0 };
+
+ EpsFlags::RgbValues
+ EpsFlags::default_color_function (const double x,
+ const double xmin,
+ const double xmax)
+ {
+ RgbValues rgb_values = { 0,0,0 };
// A difficult color scale:
// xmin = black (1)
// { 0 (3) - (4)
// { ( 4*x- xmin-3*xmax)/(xmax-xmin) (4) - (5)
- double sum = xmax+ xmin;
- double sum13 = xmin+3*xmax;
- double sum22 = 2*xmin+2*xmax;
- double sum31 = 3*xmin+ xmax;
- double dif = xmax-xmin;
- double rezdif = 1.0/dif;
-
- int where;
-
- if (x<(sum31)/4)
- where = 0;
- else if (x<(sum22)/4)
- where = 1;
- else if (x<(sum13)/4)
- where = 2;
- else
- where = 3;
+ double sum = xmax+ xmin;
+ double sum13 = xmin+3*xmax;
+ double sum22 = 2*xmin+2*xmax;
+ double sum31 = 3*xmin+ xmax;
+ double dif = xmax-xmin;
+ double rezdif = 1.0/dif;
+
+ int where;
+
+ if (x<(sum31)/4)
+ where = 0;
+ else if (x<(sum22)/4)
+ where = 1;
+ else if (x<(sum13)/4)
+ where = 2;
+ else
+ where = 3;
- if (dif!=0)
- {
- switch (where)
- {
- case 0:
- rgb_values.red = 0;
- rgb_values.green = 0;
- rgb_values.blue = (x-xmin)*4.*rezdif;
- break;
- case 1:
- rgb_values.red = 0;
- rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
- rgb_values.blue = (sum22-4.*x)*rezdif;
- break;
- case 2:
- rgb_values.red = (4*x-2*sum)*rezdif;
- rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
- rgb_values.blue = 0;
- break;
- case 3:
- rgb_values.red = 1;
- rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
- rgb_values.blue = (4.*x-sum13)*rezdif;
- default:
- break;
- }
- }
- else // White
- rgb_values.red = rgb_values.green = rgb_values.blue = 1;
+ if (dif!=0)
+ {
+ switch (where)
+ {
+ case 0:
+ rgb_values.red = 0;
+ rgb_values.green = 0;
+ rgb_values.blue = (x-xmin)*4.*rezdif;
+ break;
+ case 1:
+ rgb_values.red = 0;
+ rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
+ rgb_values.blue = (sum22-4.*x)*rezdif;
+ break;
+ case 2:
+ rgb_values.red = (4*x-2*sum)*rezdif;
+ rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
+ rgb_values.blue = 0;
+ break;
+ case 3:
+ rgb_values.red = 1;
+ rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
+ rgb_values.blue = (4.*x-sum13)*rezdif;
+ default:
+ break;
+ }
+ }
+ else // White
+ rgb_values.red = rgb_values.green = rgb_values.blue = 1;
- return rgb_values;
-}
+ return rgb_values;
+ }
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::grey_scale_color_function (const double x,
- const double xmin,
- const double xmax)
-{
- DataOutBase::EpsFlags::RgbValues rgb_values;
- rgb_values.red = rgb_values.blue = rgb_values.green
- = (x-xmin)/(xmax-xmin);
- return rgb_values;
-}
+ EpsFlags::RgbValues
+ EpsFlags::grey_scale_color_function (const double x,
+ const double xmin,
+ const double xmax)
+ {
+ EpsFlags::RgbValues rgb_values;
+ rgb_values.red = rgb_values.blue = rgb_values.green
+ = (x-xmin)/(xmax-xmin);
+ return rgb_values;
+ }
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::reverse_grey_scale_color_function (const double x,
- const double xmin,
- const double xmax)
-{
- DataOutBase::EpsFlags::RgbValues rgb_values;
- rgb_values.red = rgb_values.blue = rgb_values.green
- = 1-(x-xmin)/(xmax-xmin);
- return rgb_values;
-}
+ EpsFlags::RgbValues
+ EpsFlags::reverse_grey_scale_color_function (const double x,
+ const double xmin,
+ const double xmax)
+ {
+ EpsFlags::RgbValues rgb_values;
+ rgb_values.red = rgb_values.blue = rgb_values.green
+ = 1-(x-xmin)/(xmax-xmin);
+ return rgb_values;
+ }
-bool DataOutBase::EpsCell2d::operator < (const EpsCell2d &e) const
-{
- // note the "wrong" order in
- // which we sort the elements
- return depth > e.depth;
-}
+ bool EpsCell2d::operator < (const EpsCell2d &e) const
+ {
+ // note the "wrong" order in
+ // which we sort the elements
+ return depth > e.depth;
+ }
-void DataOutBase::EpsFlags::declare_parameters (ParameterHandler &prm)
-{
- prm.declare_entry ("Index of vector for height", "0",
- Patterns::Integer(),
- "Number of the input vector that is to be used to "
- "generate height information");
- prm.declare_entry ("Index of vector for color", "0",
- Patterns::Integer(),
- "Number of the input vector that is to be used to "
- "generate color information");
- prm.declare_entry ("Scale to width or height", "width",
- Patterns::Selection ("width|height"),
- "Whether width or height should be scaled to match "
- "the given size");
- prm.declare_entry ("Size (width or height) in eps units", "300",
- Patterns::Integer(),
- "The size (width or height) to which the eps output "
- "file is to be scaled");
- prm.declare_entry ("Line widths in eps units", "0.5",
- Patterns::Double(),
- "The width in which the postscript renderer is to "
- "plot lines");
- prm.declare_entry ("Azimut angle", "60",
- Patterns::Double(0,180),
- "Angle of the viewing position against the vertical "
- "axis");
- prm.declare_entry ("Turn angle", "30",
- Patterns::Double(0,360),
- "Angle of the viewing direction against the y-axis");
- prm.declare_entry ("Scaling for z-axis", "1",
- Patterns::Double (),
- "Scaling for the z-direction relative to the scaling "
- "used in x- and y-directions");
- prm.declare_entry ("Draw mesh lines", "true",
- Patterns::Bool(),
- "Whether the mesh lines, or only the surface should be "
- "drawn");
- prm.declare_entry ("Fill interior of cells", "true",
- Patterns::Bool(),
- "Whether only the mesh lines, or also the interior of "
- "cells should be plotted. If this flag is false, then "
- "one can see through the mesh");
- prm.declare_entry ("Color shading of interior of cells", "true",
- Patterns::Bool(),
- "Whether the interior of cells shall be shaded");
- prm.declare_entry ("Color function", "default",
- Patterns::Selection ("default|grey scale|reverse grey scale"),
- "Name of a color function used to colorize mesh lines "
- "and/or cell interiors");
-}
+ void EpsFlags::declare_parameters (ParameterHandler &prm)
+ {
+ prm.declare_entry ("Index of vector for height", "0",
+ Patterns::Integer(),
+ "Number of the input vector that is to be used to "
+ "generate height information");
+ prm.declare_entry ("Index of vector for color", "0",
+ Patterns::Integer(),
+ "Number of the input vector that is to be used to "
+ "generate color information");
+ prm.declare_entry ("Scale to width or height", "width",
+ Patterns::Selection ("width|height"),
+ "Whether width or height should be scaled to match "
+ "the given size");
+ prm.declare_entry ("Size (width or height) in eps units", "300",
+ Patterns::Integer(),
+ "The size (width or height) to which the eps output "
+ "file is to be scaled");
+ prm.declare_entry ("Line widths in eps units", "0.5",
+ Patterns::Double(),
+ "The width in which the postscript renderer is to "
+ "plot lines");
+ prm.declare_entry ("Azimut angle", "60",
+ Patterns::Double(0,180),
+ "Angle of the viewing position against the vertical "
+ "axis");
+ prm.declare_entry ("Turn angle", "30",
+ Patterns::Double(0,360),
+ "Angle of the viewing direction against the y-axis");
+ prm.declare_entry ("Scaling for z-axis", "1",
+ Patterns::Double (),
+ "Scaling for the z-direction relative to the scaling "
+ "used in x- and y-directions");
+ prm.declare_entry ("Draw mesh lines", "true",
+ Patterns::Bool(),
+ "Whether the mesh lines, or only the surface should be "
+ "drawn");
+ prm.declare_entry ("Fill interior of cells", "true",
+ Patterns::Bool(),
+ "Whether only the mesh lines, or also the interior of "
+ "cells should be plotted. If this flag is false, then "
+ "one can see through the mesh");
+ prm.declare_entry ("Color shading of interior of cells", "true",
+ Patterns::Bool(),
+ "Whether the interior of cells shall be shaded");
+ prm.declare_entry ("Color function", "default",
+ Patterns::Selection ("default|grey scale|reverse grey scale"),
+ "Name of a color function used to colorize mesh lines "
+ "and/or cell interiors");
+ }
-void DataOutBase::EpsFlags::parse_parameters (const ParameterHandler &prm)
-{
- height_vector = prm.get_integer ("Index of vector for height");
- color_vector = prm.get_integer ("Index of vector for color");
- if (prm.get ("Scale to width or height") == "width")
- size_type = width;
- else
- size_type = height;
- size = prm.get_integer ("Size (width or height) in eps units");
- line_width = prm.get_double ("Line widths in eps units");
- azimut_angle = prm.get_double ("Azimut angle");
- turn_angle = prm.get_double ("Turn angle");
- z_scaling = prm.get_double ("Scaling for z-axis");
- draw_mesh = prm.get_bool ("Draw mesh lines");
- draw_cells = prm.get_bool ("Fill interior of cells");
- shade_cells = prm.get_bool ("Color shading of interior of cells");
- if (prm.get("Color function") == "default")
- color_function = &default_color_function;
- else if (prm.get("Color function") == "grey scale")
- color_function = &grey_scale_color_function;
- else if (prm.get("Color function") == "reverse grey scale")
- color_function = &reverse_grey_scale_color_function;
- else
- // we shouldn't get here, since
- // the parameter object should
- // already have checked that the
- // given value is valid
- Assert (false, ExcInternalError());
-}
+ void EpsFlags::parse_parameters (const ParameterHandler &prm)
+ {
+ height_vector = prm.get_integer ("Index of vector for height");
+ color_vector = prm.get_integer ("Index of vector for color");
+ if (prm.get ("Scale to width or height") == "width")
+ size_type = width;
+ else
+ size_type = height;
+ size = prm.get_integer ("Size (width or height) in eps units");
+ line_width = prm.get_double ("Line widths in eps units");
+ azimut_angle = prm.get_double ("Azimut angle");
+ turn_angle = prm.get_double ("Turn angle");
+ z_scaling = prm.get_double ("Scaling for z-axis");
+ draw_mesh = prm.get_bool ("Draw mesh lines");
+ draw_cells = prm.get_bool ("Fill interior of cells");
+ shade_cells = prm.get_bool ("Color shading of interior of cells");
+ if (prm.get("Color function") == "default")
+ color_function = &default_color_function;
+ else if (prm.get("Color function") == "grey scale")
+ color_function = &grey_scale_color_function;
+ else if (prm.get("Color function") == "reverse grey scale")
+ color_function = &reverse_grey_scale_color_function;
+ else
+ // we shouldn't get here, since
+ // the parameter object should
+ // already have checked that the
+ // given value is valid
+ Assert (false, ExcInternalError());
+ }
-std::size_t
-DataOutBase::EpsFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ EpsFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::GmvFlags::GmvFlags ()
-{}
+ GmvFlags::GmvFlags ()
+ {}
-void DataOutBase::GmvFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+ void GmvFlags::declare_parameters (ParameterHandler &/*prm*/)
+ {}
-void DataOutBase::GmvFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+ void GmvFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+ {}
-std::size_t
-DataOutBase::GmvFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ GmvFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::TecplotFlags::
-TecplotFlags (const char *tecplot_binary_file_name,
- const char *zone_name)
- :
- tecplot_binary_file_name(tecplot_binary_file_name),
- zone_name(zone_name)
-{}
+ TecplotFlags::
+ TecplotFlags (const char *tecplot_binary_file_name,
+ const char *zone_name)
+ :
+ tecplot_binary_file_name(tecplot_binary_file_name),
+ zone_name(zone_name)
+ {}
-void DataOutBase::TecplotFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+ void TecplotFlags::declare_parameters (ParameterHandler &/*prm*/)
+ {}
-void DataOutBase::TecplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+ void TecplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+ {}
-std::size_t
-DataOutBase::TecplotFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ TecplotFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::VtkFlags::VtkFlags (const double time,
- const unsigned int cycle,
- const bool print_date_and_time)
- :
- time (time),
- cycle (cycle),
- print_date_and_time (print_date_and_time)
-{}
+ VtkFlags::VtkFlags (const double time,
+ const unsigned int cycle,
+ const bool print_date_and_time)
+ :
+ time (time),
+ cycle (cycle),
+ print_date_and_time (print_date_and_time)
+ {}
-void DataOutBase::VtkFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
-
+ void VtkFlags::declare_parameters (ParameterHandler &/*prm*/)
+ {}
-void DataOutBase::VtkFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+ void VtkFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+ {}
-std::size_t
-DataOutBase::VtkFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ std::size_t
+ VtkFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-DataOutBase::SvgFlags::SvgFlags (const unsigned int height_vector,
- const int azimuth_angle,
- const int polar_angle,
- const unsigned int line_thickness,
- const bool margin,
- const bool draw_colorbar)
- :
- height(4000),
- width(0),
- height_vector(height_vector),
- azimuth_angle(azimuth_angle),
- polar_angle(polar_angle),
- line_thickness(line_thickness),
- margin(margin),
- draw_colorbar(draw_colorbar)
-{}
+ Deal_II_IntermediateFlags::Deal_II_IntermediateFlags ()
+ :
+ dummy (0)
+ {}
-DataOutBase::Deal_II_IntermediateFlags::Deal_II_IntermediateFlags ()
- :
- dummy (0)
-{}
+ void Deal_II_IntermediateFlags::declare_parameters (ParameterHandler &/*prm*/)
+ {}
-void DataOutBase::Deal_II_IntermediateFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+ void Deal_II_IntermediateFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+ {}
-void DataOutBase::Deal_II_IntermediateFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+ std::size_t
+ Deal_II_IntermediateFlags::memory_consumption () const
+ {
+ // only simple data elements, so
+ // use sizeof operator
+ return sizeof (*this);
+ }
-std::size_t
-DataOutBase::Deal_II_IntermediateFlags::memory_consumption () const
-{
- // only simple data elements, so
- // use sizeof operator
- return sizeof (*this);
-}
+ OutputFormat
+ parse_output_format (const std::string &format_name)
+ {
+ if (format_name == "none")
+ return none;
-std::size_t
-DataOutBase::memory_consumption ()
-{
- return 0;
-}
+ if (format_name == "dx")
+ return dx;
+ if (format_name == "ucd")
+ return ucd;
+ if (format_name == "gnuplot")
+ return gnuplot;
+ if (format_name == "povray")
+ return povray;
-DataOutBase::OutputFormat
-DataOutBase::
-parse_output_format (const std::string &format_name)
-{
- if (format_name == "none")
- return none;
+ if (format_name == "eps")
+ return eps;
- if (format_name == "dx")
- return dx;
+ if (format_name == "gmv")
+ return gmv;
- if (format_name == "ucd")
- return ucd;
+ if (format_name == "tecplot")
+ return tecplot;
- if (format_name == "gnuplot")
- return gnuplot;
+ if (format_name == "tecplot_binary")
+ return tecplot_binary;
- if (format_name == "povray")
- return povray;
+ if (format_name == "vtk")
+ return vtk;
- if (format_name == "eps")
- return eps;
+ if (format_name == "vtu")
+ return vtu;
- if (format_name == "gmv")
- return gmv;
+ if (format_name == "deal.II intermediate")
+ return deal_II_intermediate;
- if (format_name == "tecplot")
- return tecplot;
+ if (format_name == "hdf5")
+ return hdf5;
- if (format_name == "tecplot_binary")
- return tecplot_binary;
+ AssertThrow (false,
+ ExcMessage ("The given file format name is not recognized: <"
+ + format_name + ">"));
- if (format_name == "vtk")
- return vtk;
+ // return something invalid
+ return OutputFormat(-1);
+ }
- if (format_name == "vtu")
- return vtu;
- if (format_name == "deal.II intermediate")
- return deal_II_intermediate;
- if (format_name == "hdf5")
- return hdf5;
+ std::string
+ get_output_format_names ()
+ {
+ return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|svg|deal.II intermediate";
+ }
- AssertThrow (false,
- ExcMessage ("The given file format name is not recognized: <"
- + format_name + ">"));
- // return something invalid
- return OutputFormat(-1);
-}
+ std::string
+ default_suffix (const OutputFormat output_format)
+ {
+ switch (output_format)
+ {
+ case none:
+ return "";
+ case dx:
+ return ".dx";
+ case ucd:
+ return ".inp";
+ case gnuplot:
+ return ".gnuplot";
+ case povray:
+ return ".pov";
+ case eps:
+ return ".eps";
+ case gmv:
+ return ".gmv";
+ case tecplot:
+ return ".dat";
+ case tecplot_binary:
+ return ".plt";
+ case vtk:
+ return ".vtk";
+ case vtu:
+ return ".vtu";
+ case deal_II_intermediate:
+ return ".d2";
+ case hdf5:
+ return ".h5";
+ case svg:
+ return ".svg";
+ default:
+ Assert (false, ExcNotImplemented());
+ return "";
+ }
+ }
-std::string
-DataOutBase::get_output_format_names ()
-{
- return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|svg|deal.II intermediate";
-}
+//----------------------------------------------------------------------//
+ template <int dim, int spacedim, typename STREAM>
+ void
+ write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
+ STREAM &out)
+ {
+ Assert (dim<=3, ExcNotImplemented());
+ unsigned int count = 0;
+ // We only need this point below,
+ // but it does not harm to declare
+ // it here.
+ Point<spacedim> node;
+
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+ patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ // Length of loops in all
+ // dimensions. If a dimension
+ // is not used, a loop of
+ // length one will do the job.
+ const unsigned int n1 = (dim>0) ? n : 1;
+ const unsigned int n2 = (dim>1) ? n : 1;
+ const unsigned int n3 = (dim>2) ? n : 1;
+
+ for (unsigned int i3=0; i3<n3; ++i3)
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ compute_node(node, &*patch,
+ i1,
+ i2,
+ i3,
+ n_subdivisions);
+ out.write_point(count++, node);
+ }
+ }
+ out.flush_points ();
+ }
+ template <int dim, int spacedim, typename STREAM>
+ void
+ write_cells (const std::vector<Patch<dim,spacedim> > &patches,
+ STREAM &out)
+ {
+ Assert (dim<=3, ExcNotImplemented());
+ unsigned int count = 0;
+ unsigned int first_vertex_of_patch = 0;
+ // Array to hold all the node
+ // numbers of a cell. 8 is
+ // sufficient for 3D
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+ patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ // Length of loops in all dimensons
+ const unsigned int n1 = (dim>0) ? n_subdivisions : 1;
+ const unsigned int n2 = (dim>1) ? n_subdivisions : 1;
+ const unsigned int n3 = (dim>2) ? n_subdivisions : 1;
+ // Offsets of outer loops
+ unsigned int d1 = 1;
+ unsigned int d2 = n;
+ unsigned int d3 = n*n;
+ for (unsigned int i3=0; i3<n3; ++i3)
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
+ // First write line in x direction
+ out.template write_cell<dim>(count++, offset, d1, d2, d3);
+ }
+ // finally update the number
+ // of the first vertex of this patch
+ first_vertex_of_patch += Utilities::fixed_power<dim>(n_subdivisions+1);
+ }
-std::string
-DataOutBase::
-default_suffix (const OutputFormat output_format)
-{
- switch (output_format)
- {
- case none:
- return "";
- case dx:
- return ".dx";
- case ucd:
- return ".inp";
- case gnuplot:
- return ".gnuplot";
- case povray:
- return ".pov";
- case eps:
- return ".eps";
- case gmv:
- return ".gmv";
- case tecplot:
- return ".dat";
- case tecplot_binary:
- return ".plt";
- case vtk:
- return ".vtk";
- case vtu:
- return ".vtu";
- case deal_II_intermediate:
- return ".d2";
- case hdf5:
- return ".h5";
- case svg:
- return ".svg";
- default:
- Assert (false, ExcNotImplemented());
- return "";
- }
-}
+ out.flush_cells ();
+ }
-//----------------------------------------------------------------------//
+ template <int dim, int spacedim, class STREAM>
+ void
+ write_data (
+ const std::vector<Patch<dim,spacedim> > &patches,
+ unsigned int n_data_sets,
+ const bool double_precision,
+ STREAM &out)
+ {
+ Assert (dim<=3, ExcNotImplemented());
+ unsigned int count = 0;
-template <int dim, int spacedim, typename STREAM>
-void
-DataOutBase::write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
- STREAM &out)
-{
- Assert (dim<=3, ExcNotImplemented());
- unsigned int count = 0;
- // We only need this point below,
- // but it does not harm to declare
- // it here.
- Point<spacedim> node;
-
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- // Length of loops in all
- // dimensions. If a dimension
- // is not used, a loop of
- // length one will do the job.
- const unsigned int n1 = (dim>0) ? n : 1;
- const unsigned int n2 = (dim>1) ? n : 1;
- const unsigned int n3 = (dim>2) ? n : 1;
-
- for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch
+ = patches.begin();
+ patch != patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ // Length of loops in all dimensions
+ Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
+ Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+ ExcInvalidDatasetSize (patch->data.n_cols(), n));
+
+ std::vector<float> floats(n_data_sets);
+ std::vector<double> doubles(n_data_sets);
+
+ // Data is already in
+ // lexicographic ordering
+ for (unsigned int i=0; i<Utilities::fixed_power<dim>(n); ++i, ++count)
+ if (double_precision)
{
- compute_node(node, &*patch,
- i1,
- i2,
- i3,
- n_subdivisions);
- out.write_point(count++, node);
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ doubles[data_set] = patch->data(data_set, i);
+ out.write_dataset(count, doubles);
}
- }
- out.flush_points ();
-}
-
-template <int dim, int spacedim, typename STREAM>
-void
-DataOutBase::write_cells (const std::vector<Patch<dim,spacedim> > &patches,
- STREAM &out)
-{
- Assert (dim<=3, ExcNotImplemented());
- unsigned int count = 0;
- unsigned int first_vertex_of_patch = 0;
- // Array to hold all the node
- // numbers of a cell. 8 is
- // sufficient for 3D
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensons
- const unsigned int n1 = (dim>0) ? n_subdivisions : 1;
- const unsigned int n2 = (dim>1) ? n_subdivisions : 1;
- const unsigned int n3 = (dim>2) ? n_subdivisions : 1;
- // Offsets of outer loops
- unsigned int d1 = 1;
- unsigned int d2 = n;
- unsigned int d3 = n*n;
- for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
+ else
{
- const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
- // First write line in x direction
- out.template write_cell<dim>(count++, offset, d1, d2, d3);
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ floats[data_set] = patch->data(data_set, i);
+ out.write_dataset(count, floats);
}
- // finally update the number
- // of the first vertex of this patch
- first_vertex_of_patch += Utilities::fixed_power<dim>(n_subdivisions+1);
- }
-
- out.flush_cells ();
-}
+ }
+ }
-template <int dim, int spacedim, class STREAM>
-void
-DataOutBase::write_data (
- const std::vector<Patch<dim,spacedim> > &patches,
- unsigned int n_data_sets,
- const bool double_precision,
- STREAM &out)
-{
- Assert (dim<=3, ExcNotImplemented());
- unsigned int count = 0;
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch
- = patches.begin();
- patch != patches.end(); ++patch)
+ namespace
+ {
+ /**
+ * This function projects a three-dimensional point (Point<3> point)
+ * onto a two-dimensional image plane, specified by the position of
+ * the camera viewing system (Point<3> camera_position), camera
+ * direction (Point<3> camera_position), camera horizontal (Point<3>
+ * camera_horizontal, necessary for the correct alignment of the
+ * later images), and the focus of the camera (float camera_focus).
+ */
+ Point<2> svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus)
{
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensions
- Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
- Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n));
-
- std::vector<float> floats(n_data_sets);
- std::vector<double> doubles(n_data_sets);
-
- // Data is already in
- // lexicographic ordering
- for (unsigned int i=0; i<Utilities::fixed_power<dim>(n); ++i, ++count)
- if (double_precision)
- {
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- doubles[data_set] = patch->data(data_set, i);
- out.write_dataset(count, doubles);
- }
- else
- {
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- floats[data_set] = patch->data(data_set, i);
- out.write_dataset(count, floats);
- }
+ Point<3> camera_vertical;
+ camera_vertical[0] = camera_horizontal[1] * camera_direction[2] - camera_horizontal[2] * camera_direction[1];
+ camera_vertical[1] = camera_horizontal[2] * camera_direction[0] - camera_horizontal[0] * camera_direction[2];
+ camera_vertical[2] = camera_horizontal[0] * camera_direction[1] - camera_horizontal[1] * camera_direction[0];
+
+ float phi;
+ phi = camera_focus;
+ phi /= (point[0] - camera_position[0]) * camera_direction[0] + (point[1] - camera_position[1]) * camera_direction[1] + (point[2] - camera_position[2]) * camera_direction[2];
+
+ Point<3> projection;
+ projection[0] = camera_position[0] + phi * (point[0] - camera_position[0]);
+ projection[1] = camera_position[1] + phi * (point[1] - camera_position[1]);
+ projection[2] = camera_position[2] + phi * (point[2] - camera_position[2]);
+
+ Point<2> projection_decomposition;
+ projection_decomposition[0] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_horizontal[0];
+ projection_decomposition[0] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_horizontal[1];
+ projection_decomposition[0] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_horizontal[2];
+
+ projection_decomposition[1] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_vertical[0];
+ projection_decomposition[1] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_vertical[1];
+ projection_decomposition[1] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_vertical[2];
+
+ return projection_decomposition;
}
-}
-
-Point<2> DataOutBase::svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus)
-{
- Point<3> camera_vertical;
- camera_vertical[0] = camera_horizontal[1] * camera_direction[2] - camera_horizontal[2] * camera_direction[1];
- camera_vertical[1] = camera_horizontal[2] * camera_direction[0] - camera_horizontal[0] * camera_direction[2];
- camera_vertical[2] = camera_horizontal[0] * camera_direction[1] - camera_horizontal[1] * camera_direction[0];
-
- float phi;
- phi = camera_focus;
- phi /= (point[0] - camera_position[0]) * camera_direction[0] + (point[1] - camera_position[1]) * camera_direction[1] + (point[2] - camera_position[2]) * camera_direction[2];
-
- Point<3> projection;
- projection[0] = camera_position[0] + phi * (point[0] - camera_position[0]);
- projection[1] = camera_position[1] + phi * (point[1] - camera_position[1]);
- projection[2] = camera_position[2] + phi * (point[2] - camera_position[2]);
-
- Point<2> projection_decomposition;
- projection_decomposition[0] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_horizontal[0];
- projection_decomposition[0] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_horizontal[1];
- projection_decomposition[0] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_horizontal[2];
-
- projection_decomposition[1] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_vertical[0];
- projection_decomposition[1] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_vertical[1];
- projection_decomposition[1] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_vertical[2];
-
- return projection_decomposition;
-}
-Point<6> DataOutBase::svg_get_gradient_parameters(Point<3> points[])
-{
- Point<3> v_min, v_max, v_inter;
+ /**
+ * Function to compute the gradient parameters for a triangle with
+ * given values for the vertices.
+ */
+ Point<6> svg_get_gradient_parameters(Point<3> points[])
+ {
+ Point<3> v_min, v_max, v_inter;
- // Use the Bubblesort algorithm to sort the points with respect to the third coordinate
- int i, j;
+ // Use the Bubblesort algorithm to sort the points with respect to the third coordinate
+ int i, j;
- for (i = 0; i < 2; ++i)
- {
- for (j = 0; j < 2-i; ++j)
+ for (i = 0; i < 2; ++i)
{
- if (points[j][2] > points[j + 1][2])
+ for (j = 0; j < 2-i; ++j)
{
- Point<3> temp = points[j];
- points[j] = points[j+1];
- points[j+1] = temp;
+ if (points[j][2] > points[j + 1][2])
+ {
+ Point<3> temp = points[j];
+ points[j] = points[j+1];
+ points[j+1] = temp;
+ }
}
}
- }
- // save the related three-dimensional vectors v_min, v_inter, and v_max
- v_min = points[0];
- v_inter = points[1];
- v_max = points[2];
+ // save the related three-dimensional vectors v_min, v_inter, and v_max
+ v_min = points[0];
+ v_inter = points[1];
+ v_max = points[2];
- Point<2> A[2];
- Point<2> b, gradient;
+ Point<2> A[2];
+ Point<2> b, gradient;
- // determine the plane offset c
- A[0][0] = v_max[0] - v_min[0];
- A[0][1] = v_inter[0] - v_min[0];
- A[1][0] = v_max[1] - v_min[1];
- A[1][1] = v_inter[1] - v_min[1];
+ // determine the plane offset c
+ A[0][0] = v_max[0] - v_min[0];
+ A[0][1] = v_inter[0] - v_min[0];
+ A[1][0] = v_max[1] - v_min[1];
+ A[1][1] = v_inter[1] - v_min[1];
- b[0] = - v_min[0];
- b[1] = - v_min[1];
+ b[0] = - v_min[0];
+ b[1] = - v_min[1];
- double x, sum;
- bool col_change = false;
+ double x, sum;
+ bool col_change = false;
- if (A[0][0] == 0)
- {
- col_change = true;
+ if (A[0][0] == 0)
+ {
+ col_change = true;
- A[0][0] = A[0][1];
- A[0][1] = 0;
+ A[0][0] = A[0][1];
+ A[0][1] = 0;
- double temp = A[1][0];
- A[1][0] = A[1][1];
- A[1][1] = temp;
- }
+ double temp = A[1][0];
+ A[1][0] = A[1][1];
+ A[1][1] = temp;
+ }
- for (unsigned int k = 0; k < 1; k++)
- {
- for (unsigned int i = k+1; i < 2; i++)
+ for (unsigned int k = 0; k < 1; k++)
{
- x = A[i][k] / A[k][k];
+ for (unsigned int i = k+1; i < 2; i++)
+ {
+ x = A[i][k] / A[k][k];
- for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+ for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
- b[i] = b[i] - b[k]*x;
+ b[i] = b[i] - b[k]*x;
+ }
}
- }
- b[1] = b[1] / A[1][1];
+ b[1] = b[1] / A[1][1];
- for (int i = 0; i >= 0; i--)
- {
- sum = b[i];
+ for (int i = 0; i >= 0; i--)
+ {
+ sum = b[i];
- for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
+ for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
- b[i] = sum / A[i][i];
- }
+ b[i] = sum / A[i][i];
+ }
- if (col_change)
- {
- double temp = b[0];
- b[0] = b[1];
- b[1] = temp;
- }
+ if (col_change)
+ {
+ double temp = b[0];
+ b[0] = b[1];
+ b[1] = temp;
+ }
- double c = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) + v_min[2];
+ double c = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) + v_min[2];
- // Determine the first entry of the gradient (phi, cf. documentation)
- A[0][0] = v_max[0] - v_min[0];
- A[0][1] = v_inter[0] - v_min[0];
- A[1][0] = v_max[1] - v_min[1];
- A[1][1] = v_inter[1] - v_min[1];
+ // Determine the first entry of the gradient (phi, cf. documentation)
+ A[0][0] = v_max[0] - v_min[0];
+ A[0][1] = v_inter[0] - v_min[0];
+ A[1][0] = v_max[1] - v_min[1];
+ A[1][1] = v_inter[1] - v_min[1];
- b[0] = 1.0 - v_min[0];
- b[1] = - v_min[1];
+ b[0] = 1.0 - v_min[0];
+ b[1] = - v_min[1];
- col_change = false;
+ col_change = false;
- if (A[0][0] == 0)
- {
- col_change = true;
+ if (A[0][0] == 0)
+ {
+ col_change = true;
- A[0][0] = A[0][1];
- A[0][1] = 0;
+ A[0][0] = A[0][1];
+ A[0][1] = 0;
- double temp = A[1][0];
- A[1][0] = A[1][1];
- A[1][1] = temp;
- }
+ double temp = A[1][0];
+ A[1][0] = A[1][1];
+ A[1][1] = temp;
+ }
- for (unsigned int k = 0; k < 1; k++)
- {
- for (unsigned int i = k+1; i < 2; i++)
+ for (unsigned int k = 0; k < 1; k++)
{
- x = A[i][k] / A[k][k];
+ for (unsigned int i = k+1; i < 2; i++)
+ {
+ x = A[i][k] / A[k][k];
- for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+ for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
- b[i] = b[i] - b[k] * x;
+ b[i] = b[i] - b[k] * x;
+ }
}
- }
- b[1]=b[1] / A[1][1];
+ b[1]=b[1] / A[1][1];
- for (int i = 0; i >= 0; i--)
- {
- sum = b[i];
+ for (int i = 0; i >= 0; i--)
+ {
+ sum = b[i];
- for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j]*b[j];
+ for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j]*b[j];
- b[i] = sum / A[i][i];
- }
+ b[i] = sum / A[i][i];
+ }
- if (col_change)
- {
- double temp = b[0];
- b[0] = b[1];
- b[1] = temp;
- }
+ if (col_change)
+ {
+ double temp = b[0];
+ b[0] = b[1];
+ b[1] = temp;
+ }
- gradient[0] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
+ gradient[0] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
- // determine the second entry of the gradient
- A[0][0] = v_max[0] - v_min[0];
- A[0][1] = v_inter[0] - v_min[0];
- A[1][0] = v_max[1] - v_min[1];
- A[1][1] = v_inter[1] - v_min[1];
+ // determine the second entry of the gradient
+ A[0][0] = v_max[0] - v_min[0];
+ A[0][1] = v_inter[0] - v_min[0];
+ A[1][0] = v_max[1] - v_min[1];
+ A[1][1] = v_inter[1] - v_min[1];
- b[0] = - v_min[0];
- b[1] = 1.0 - v_min[1];
+ b[0] = - v_min[0];
+ b[1] = 1.0 - v_min[1];
- col_change = false;
+ col_change = false;
- if (A[0][0] == 0)
- {
- col_change = true;
+ if (A[0][0] == 0)
+ {
+ col_change = true;
- A[0][0] = A[0][1];
- A[0][1] = 0;
+ A[0][0] = A[0][1];
+ A[0][1] = 0;
- double temp = A[1][0];
- A[1][0] = A[1][1];
- A[1][1] = temp;
- }
+ double temp = A[1][0];
+ A[1][0] = A[1][1];
+ A[1][1] = temp;
+ }
- for (unsigned int k = 0; k < 1; k++)
- {
- for (unsigned int i = k+1; i < 2; i++)
+ for (unsigned int k = 0; k < 1; k++)
{
- x = A[i][k] / A[k][k];
+ for (unsigned int i = k+1; i < 2; i++)
+ {
+ x = A[i][k] / A[k][k];
- for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+ for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
- b[i] = b[i] - b[k] * x;
+ b[i] = b[i] - b[k] * x;
+ }
}
- }
-
- b[1] = b[1] / A[1][1];
-
- for (int i = 0; i >= 0; i--)
- {
- sum = b[i];
- for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
+ b[1] = b[1] / A[1][1];
- b[i] = sum / A[i][i];
- }
+ for (int i = 0; i >= 0; i--)
+ {
+ sum = b[i];
- if (col_change)
- {
- double temp = b[0];
- b[0] = b[1];
- b[1] = temp;
- }
+ for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
- gradient[1] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
+ b[i] = sum / A[i][i];
+ }
- // normalize the gradient
- double gradient_norm = sqrt(pow(gradient[0], 2.0) + pow(gradient[1], 2.0));
- gradient[0] /= gradient_norm;
- gradient[1] /= gradient_norm;
+ if (col_change)
+ {
+ double temp = b[0];
+ b[0] = b[1];
+ b[1] = temp;
+ }
- double lambda = - gradient[0] * (v_min[0] - v_max[0]) - gradient[1] * (v_min[1] - v_max[1]);
+ gradient[1] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
- Point<6> gradient_parameters(true);
+ // normalize the gradient
+ double gradient_norm = sqrt(pow(gradient[0], 2.0) + pow(gradient[1], 2.0));
+ gradient[0] /= gradient_norm;
+ gradient[1] /= gradient_norm;
- gradient_parameters[0] = v_min[0];
- gradient_parameters[1] = v_min[1];
+ double lambda = - gradient[0] * (v_min[0] - v_max[0]) - gradient[1] * (v_min[1] - v_max[1]);
- gradient_parameters[2] = v_min[0] + lambda * gradient[0];
- gradient_parameters[3] = v_min[1] + lambda * gradient[1];
+ Point<6> gradient_parameters(true);
- gradient_parameters[4] = v_min[2];
- gradient_parameters[5] = v_max[2];
+ gradient_parameters[0] = v_min[0];
+ gradient_parameters[1] = v_min[1];
- return gradient_parameters;
-}
+ gradient_parameters[2] = v_min[0] + lambda * gradient[0];
+ gradient_parameters[3] = v_min[1] + lambda * gradient[1];
+ gradient_parameters[4] = v_min[2];
+ gradient_parameters[5] = v_max[2];
-bool DataOutBase::SvgCell::operator < (const SvgCell &e) const
-{
- // note the "wrong" order in
- // which we sort the elements
- return depth > e.depth;
-}
+ return gradient_parameters;
+ }
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const UcdFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ template <int dim, int spacedim>
+ void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const UcdFlags &flags,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- return;
+ if (patches.size() == 0)
+ return;
#endif
- const unsigned int n_data_sets = data_names.size();
+ const unsigned int n_data_sets = data_names.size();
- UcdStream ucd_out(out, flags);
+ UcdStream ucd_out(out, flags);
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim> (patches, n_nodes, n_cells);
- ///////////////////////
- // preamble
- if (flags.write_preamble)
- {
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the UCD format see the AVS Developer's guide."
- << '\n'
- << "#" << '\n';
- }
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim> (patches, n_nodes, n_cells);
+ ///////////////////////
+ // preamble
+ if (flags.write_preamble)
+ {
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "# This file was generated by the deal.II library." << '\n'
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the UCD format see the AVS Developer's guide."
+ << '\n'
+ << "#" << '\n';
+ }
- // start with ucd data
- out << n_nodes << ' '
- << n_cells << ' '
- << n_data_sets << ' '
- << 0 << ' ' // no cell data at present
- << 0 // no model data
- << '\n';
+ // start with ucd data
+ out << n_nodes << ' '
+ << n_cells << ' '
+ << n_data_sets << ' '
+ << 0 << ' ' // no cell data at present
+ << 0 // no model data
+ << '\n';
- write_nodes(patches, ucd_out);
- out << '\n';
+ write_nodes(patches, ucd_out);
+ out << '\n';
- write_cells(patches, ucd_out);
- out << '\n';
+ write_cells(patches, ucd_out);
+ out << '\n';
- /////////////////////////////
- // now write data
- if (n_data_sets != 0)
- {
- out << n_data_sets << " "; // number of vectors
- for (unsigned int i=0; i<n_data_sets; ++i)
- out << 1 << ' '; // number of components;
- // only 1 supported presently
- out << '\n';
+ /////////////////////////////
+ // now write data
+ if (n_data_sets != 0)
+ {
+ out << n_data_sets << " "; // number of vectors
+ for (unsigned int i=0; i<n_data_sets; ++i)
+ out << 1 << ' '; // number of components;
+ // only 1 supported presently
+ out << '\n';
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << data_names[data_set]
- << ",dimensionless" // no units supported at present
- << '\n';
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << data_names[data_set]
+ << ",dimensionless" // no units supported at present
+ << '\n';
- write_data(patches, n_data_sets, true, ucd_out);
- }
- // make sure everything now gets to
- // disk
- out.flush ();
+ write_data(patches, n_data_sets, true, ucd_out);
+ }
+ // make sure everything now gets to
+ // disk
+ out.flush ();
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_dx (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const DXFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ template <int dim, int spacedim>
+ void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const DXFlags &flags,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- return;
+ if (patches.size() == 0)
+ return;
#endif
- // Stream with special features for dx output
- DXStream dx_out(out, flags);
+ // Stream with special features for dx output
+ DXStream dx_out(out, flags);
- // Variable counting the offset of
- // binary data.
- unsigned int offset = 0;
+ // Variable counting the offset of
+ // binary data.
+ unsigned int offset = 0;
- const unsigned int n_data_sets = data_names.size();
-
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // start with vertices order is
- // lexicographical, x varying
- // fastest
- out << "object \"vertices\" class array type float rank 1 shape " << spacedim
- << " items " << n_nodes;
-
- if (flags.coordinates_binary)
- {
- out << " lsb ieee data 0" << '\n';
- offset += n_nodes * spacedim * sizeof(float);
- }
- else
- {
- out << " data follows" << '\n';
- write_nodes(patches, dx_out);
- }
+ const unsigned int n_data_sets = data_names.size();
- ///////////////////////////////
- // first write the coordinates of all vertices
-
- /////////////////////////////////////////
- // write cells
- out << "object \"cells\" class array type int rank 1 shape "
- << GeometryInfo<dim>::vertices_per_cell
- << " items " << n_cells;
-
- if (flags.int_binary)
- {
- out << " lsb binary data " << offset << '\n';
- offset += n_cells * sizeof (int);
- }
- else
- {
- out << " data follows" << '\n';
- write_cells(patches, dx_out);
- out << '\n';
- }
-
-
- out << "attribute \"element type\" string \"";
- if (dim==1) out << "lines";
- if (dim==2) out << "quads";
- if (dim==3) out << "cubes";
- out << "\"" << '\n'
- << "attribute \"ref\" string \"positions\"" << '\n';
-
-//TODO:[GK] Patches must be of same size!
- /////////////////////////////
- // write neighbor information
- if (flags.write_neighbors)
- {
- out << "object \"neighbors\" class array type int rank 1 shape "
- << GeometryInfo<dim>::faces_per_cell
- << " items " << n_cells
- << " data follows";
-
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n = patch->n_subdivisions;
- const unsigned int n1 = (dim>0) ? n : 1;
- const unsigned int n2 = (dim>1) ? n : 1;
- const unsigned int n3 = (dim>2) ? n : 1;
- unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
- unsigned int dx = 1;
- unsigned int dy = n;
- unsigned int dz = n*n;
-
- const unsigned int patch_start = patch->patch_index * cells_per_patch;
-
- for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- const unsigned int nx = i1*dx;
- const unsigned int ny = i2*dy;
- const unsigned int nz = i3*dz;
-
- out << '\n';
- // Direction -x
- // Last cell in row
- // of other patch
- if (i1==0)
- {
- const unsigned int nn = patch->neighbors[0];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+ny+nz+dx*(n-1));
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx-dx+ny+nz;
- }
- // Direction +x
- // First cell in row
- // of other patch
- if (i1 == n-1)
- {
- const unsigned int nn = patch->neighbors[1];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+ny+nz);
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx+dx+ny+nz;
- }
- if (dim<2)
- continue;
- // Direction -y
- if (i2==0)
- {
- const unsigned int nn = patch->neighbors[2];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+nz+dy*(n-1));
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx+ny-dy+nz;
- }
- // Direction +y
- if (i2 == n-1)
- {
- const unsigned int nn = patch->neighbors[3];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+nz);
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx+ny+dy+nz;
- }
- if (dim<3)
- continue;
-
- // Direction -z
- if (i3==0)
- {
- const unsigned int nn = patch->neighbors[4];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+ny+dz*(n-1));
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx+ny+nz-dz;
- }
- // Direction +z
- if (i3 == n-1)
- {
- const unsigned int nn = patch->neighbors[5];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+ny);
- else
- out << "-1";
- }
- else
- {
- out << '\t'
- << patch_start+nx+ny+nz+dz;
- }
- }
- out << '\n';
- }
- }
- /////////////////////////////
- // now write data
- if (n_data_sets != 0)
- {
- out << "object \"data\" class array type float rank 1 shape "
- << n_data_sets
- << " items " << n_nodes;
-
- if (flags.data_binary)
- {
- out << " lsb ieee data " << offset << '\n';
- offset += n_data_sets * n_nodes * ((flags.data_double)
- ? sizeof(double)
- : sizeof(float));
- }
- else
- {
- out << " data follows" << '\n';
- write_data(patches, n_data_sets, flags.data_double, dx_out);
- }
-
- // loop over all patches
- out << "attribute \"dep\" string \"positions\"" << '\n';
- }
- else
- {
- out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
- << '\n' << '0' << '\n';
- }
-
- // no model data
-
- out << "object \"deal data\" class field" << '\n'
- << "component \"positions\" value \"vertices\"" << '\n'
- << "component \"connections\" value \"cells\"" << '\n'
- << "component \"data\" value \"data\"" << '\n';
-
- if (flags.write_neighbors)
- out << "component \"neighbors\" value \"neighbors\"" << '\n';
-
- if (true)
- {
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "attribute \"created\" string \""
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday
- << ' '
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '"' << '\n';
- }
-
- out << "end" << '\n';
- // Write all binary data now
- if (flags.coordinates_binary)
- write_nodes(patches, dx_out);
- if (flags.int_binary)
- write_cells(patches, dx_out);
- if (flags.data_binary)
- write_data(patches, n_data_sets, flags.data_double, dx_out);
-
- // make sure everything now gets to
- // disk
- out.flush ();
-
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+ // start with vertices order is
+ // lexicographical, x varying
+ // fastest
+ out << "object \"vertices\" class array type float rank 1 shape " << spacedim
+ << " items " << n_nodes;
+ if (flags.coordinates_binary)
+ {
+ out << " lsb ieee data 0" << '\n';
+ offset += n_nodes * spacedim * sizeof(float);
+ }
+ else
+ {
+ out << " data follows" << '\n';
+ write_nodes(patches, dx_out);
+ }
+ ///////////////////////////////
+ // first write the coordinates of all vertices
-template <int dim, int spacedim>
-void DataOutBase::write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const GnuplotFlags &/*flags*/,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ /////////////////////////////////////////
+ // write cells
+ out << "object \"cells\" class array type int rank 1 shape "
+ << GeometryInfo<dim>::vertices_per_cell
+ << " items " << n_cells;
-#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
-#else
- if (patches.size() == 0)
- return;
-#endif
+ if (flags.int_binary)
+ {
+ out << " lsb binary data " << offset << '\n';
+ offset += n_cells * sizeof (int);
+ }
+ else
+ {
+ out << " data follows" << '\n';
+ write_cells(patches, dx_out);
+ out << '\n';
+ }
- const unsigned int n_data_sets = data_names.size();
- // write preamble
- if (true)
- {
- // block this to have local
- // variables destroyed after
- // use
- const std::time_t time1= std::time (0);
- const std::tm *time = std::localtime(&time1);
- out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the GNUPLOT format see the GNUPLOT manual."
- << '\n'
- << "#" << '\n'
- << "# ";
+ out << "attribute \"element type\" string \"";
+ if (dim==1) out << "lines";
+ if (dim==2) out << "quads";
+ if (dim==3) out << "cubes";
+ out << "\"" << '\n'
+ << "attribute \"ref\" string \"positions\"" << '\n';
- switch (spacedim)
- {
- case 1:
- out << "<x> ";
- break;
- case 2:
- out << "<x> <y> ";
- break;
- case 3:
- out << "<x> <y> <z> ";
- break;
+//TODO:[GK] Patches must be of same size!
+ /////////////////////////////
+ // write neighbor information
+ if (flags.write_neighbors)
+ {
+ out << "object \"neighbors\" class array type int rank 1 shape "
+ << GeometryInfo<dim>::faces_per_cell
+ << " items " << n_cells
+ << " data follows";
+
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+ patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n = patch->n_subdivisions;
+ const unsigned int n1 = (dim>0) ? n : 1;
+ const unsigned int n2 = (dim>1) ? n : 1;
+ const unsigned int n3 = (dim>2) ? n : 1;
+ unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
+ unsigned int dx = 1;
+ unsigned int dy = n;
+ unsigned int dz = n*n;
+
+ const unsigned int patch_start = patch->patch_index * cells_per_patch;
+
+ for (unsigned int i3=0; i3<n3; ++i3)
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ const unsigned int nx = i1*dx;
+ const unsigned int ny = i2*dy;
+ const unsigned int nz = i3*dz;
+
+ out << '\n';
+ // Direction -x
+ // Last cell in row
+ // of other patch
+ if (i1==0)
+ {
+ const unsigned int nn = patch->neighbors[0];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz+dx*(n-1));
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx-dx+ny+nz;
+ }
+ // Direction +x
+ // First cell in row
+ // of other patch
+ if (i1 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[1];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz);
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx+dx+ny+nz;
+ }
+ if (dim<2)
+ continue;
+ // Direction -y
+ if (i2==0)
+ {
+ const unsigned int nn = patch->neighbors[2];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz+dy*(n-1));
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx+ny-dy+nz;
+ }
+ // Direction +y
+ if (i2 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[3];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz);
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx+ny+dy+nz;
+ }
+ if (dim<3)
+ continue;
+
+ // Direction -z
+ if (i3==0)
+ {
+ const unsigned int nn = patch->neighbors[4];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny+dz*(n-1));
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx+ny+nz-dz;
+ }
+ // Direction +z
+ if (i3 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[5];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny);
+ else
+ out << "-1";
+ }
+ else
+ {
+ out << '\t'
+ << patch_start+nx+ny+nz+dz;
+ }
+ }
+ out << '\n';
+ }
+ }
+ /////////////////////////////
+ // now write data
+ if (n_data_sets != 0)
+ {
+ out << "object \"data\" class array type float rank 1 shape "
+ << n_data_sets
+ << " items " << n_nodes;
- default:
- Assert (false, ExcNotImplemented());
- }
+ if (flags.data_binary)
+ {
+ out << " lsb ieee data " << offset << '\n';
+ offset += n_data_sets * n_nodes * ((flags.data_double)
+ ? sizeof(double)
+ : sizeof(float));
+ }
+ else
+ {
+ out << " data follows" << '\n';
+ write_data(patches, n_data_sets, flags.data_double, dx_out);
+ }
- for (unsigned int i=0; i<data_names.size(); ++i)
- out << '<' << data_names[i] << "> ";
- out << '\n';
- }
+ // loop over all patches
+ out << "attribute \"dep\" string \"positions\"" << '\n';
+ }
+ else
+ {
+ out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
+ << '\n' << '0' << '\n';
+ }
+ // no model data
- // loop over all patches
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch != patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensions
- const unsigned int n1 = (dim>0) ? n : 1;
- const unsigned int n2 = (dim>1) ? n : 1;
- const unsigned int n3 = (dim>2) ? n : 1;
- unsigned int d1 = 1;
- unsigned int d2 = n;
- unsigned int d3 = n*n;
-
- Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
- Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
- Point<spacedim> this_point;
- Point<spacedim> node;
- if (dim<3)
- {
- for (unsigned int i2=0; i2<n2; ++i2)
- {
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- // compute coordinates for
- // this patch point
- compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
- out << node << ' ';
+ out << "object \"deal data\" class field" << '\n'
+ << "component \"positions\" value \"vertices\"" << '\n'
+ << "component \"connections\" value \"cells\"" << '\n'
+ << "component \"data\" value \"data\"" << '\n';
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << patch->data(data_set,i1*d1+i2*d2) << ' ';
- out << '\n';
- }
- // end of row in patch
- if (dim>1)
- out << '\n';
- }
- // end of patch
- if (dim==1)
- out << '\n';
- out << '\n';
- }
- else if (dim==3)
- {
- // for all grid points: draw
- // lines into all positive
- // coordinate directions if
- // there is another grid point
- // there
- for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- // compute coordinates for
- // this patch point
- compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
- // line into positive x-direction
- // if possible
- if (i1 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
- out << '\n';
-
- // end of line
- out << '\n'
- << '\n';
- }
+ if (flags.write_neighbors)
+ out << "component \"neighbors\" value \"neighbors\"" << '\n';
- // line into positive y-direction
- // if possible
- if (i2 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set, i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
- out << '\n';
-
- // end of line
- out << '\n'
- << '\n';
- }
+ if (true)
+ {
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "attribute \"created\" string \""
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday
+ << ' '
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '"' << '\n';
+ }
- // line into positive z-direction
- // if possible
- if (i3 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
- out << '\n';
- // end of line
- out << '\n'
- << '\n';
- }
+ out << "end" << '\n';
+ // Write all binary data now
+ if (flags.coordinates_binary)
+ write_nodes(patches, dx_out);
+ if (flags.int_binary)
+ write_cells(patches, dx_out);
+ if (flags.data_binary)
+ write_data(patches, n_data_sets, flags.data_double, dx_out);
- }
- }
- else
- Assert (false, ExcNotImplemented());
- }
- // make sure everything now gets to
- // disk
- out.flush ();
+ // make sure everything now gets to
+ // disk
+ out.flush ();
- AssertThrow (out, ExcIO());
-}
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_povray (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const PovrayFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ template <int dim, int spacedim>
+ void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const GnuplotFlags &/*flags*/,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- return;
+ if (patches.size() == 0)
+ return;
#endif
- Assert (dim==2, ExcNotImplemented()); // only for 2-D surfaces on a 2-D plane
- Assert (spacedim==2, ExcNotImplemented());
-
- const unsigned int n_data_sets = data_names.size();
-
- // write preamble
- if (true)
- {
- // block this to have local
- // variables destroyed after use
- const std::time_t time1= std::time (0);
- const std::tm *time = std::localtime(&time1);
- out << "/* This file was generated by the deal.II library." << '\n'
- << " Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << " Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << '\n'
- << " For a description of the POVRAY format see the POVRAY manual."
- << '\n'
- << "*/ " << '\n';
- // include files
- out << "#include \"colors.inc\" " << '\n'
- << "#include \"textures.inc\" " << '\n';
+ const unsigned int n_data_sets = data_names.size();
+ // write preamble
+ if (true)
+ {
+ // block this to have local
+ // variables destroyed after
+ // use
+ const std::time_t time1= std::time (0);
+ const std::tm *time = std::localtime(&time1);
+ out << "# This file was generated by the deal.II library." << '\n'
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the GNUPLOT format see the GNUPLOT manual."
+ << '\n'
+ << "#" << '\n'
+ << "# ";
- // use external include file for textures,
- // camera and light
- if (flags.external_data)
- out << "#include \"data.inc\" " << '\n';
- else // all definitions in data file
- {
- // camera
- out << '\n' << '\n'
- << "camera {" << '\n'
- << " location <1,4,-7>" << '\n'
- << " look_at <0,0,0>" << '\n'
- << " angle 30" << '\n'
- << "}" << '\n';
-
- // light
- out << '\n'
- << "light_source {" << '\n'
- << " <1,4,-7>" << '\n'
- << " color Grey" << '\n'
- << "}" << '\n';
- out << '\n'
- << "light_source {" << '\n'
- << " <0,20,0>" << '\n'
- << " color White" << '\n'
- << "}" << '\n';
- }
- }
-
- // max. and min. heigth of solution
- typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- Assert(patch!=patches.end(), ExcInternalError());
- double hmin=patch->data(0,0);
- double hmax=patch->data(0,0);
-
- for (; patch != patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
-
- Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
- Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ switch (spacedim)
{
- const int dl = i*(n_subdivisions+1)+j;
- if (patch->data(0,dl)<hmin)
- hmin=patch->data(0,dl);
- if (patch->data(0,dl)>hmax)
- hmax=patch->data(0,dl);
- }
- }
-
- out << "#declare HMIN=" << hmin << ";" << '\n'
- << "#declare HMAX=" << hmax << ";" << '\n' << '\n';
-
- if (!flags.external_data)
- {
- // texture with scaled niveau lines
- // 10 lines in the surface
- out << "#declare Tex=texture{" << '\n'
- << " pigment {" << '\n'
- << " gradient y" << '\n'
- << " scale y*(HMAX-HMIN)*" << 0.1 << '\n'
- << " color_map {" << '\n'
- << " [0.00 color Light_Purple] " << '\n'
- << " [0.95 color Light_Purple] " << '\n'
- << " [1.00 color White] " << '\n'
- << "} } }" << '\n' << '\n';
- }
-
- if (!flags.bicubic_patch)
- {
- // start of mesh header
- out << '\n'
- << "mesh {" << '\n';
- }
+ case 1:
+ out << "<x> ";
+ break;
+ case 2:
+ out << "<x> <y> ";
+ break;
+ case 3:
+ out << "<x> <y> <z> ";
+ break;
- // loop over all patches
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch != patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- const unsigned int d1=1;
- const unsigned int d2=n;
-
- Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
- Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
-
- std::vector<Point<spacedim> > ver(n*n);
-
- for (unsigned int i2=0; i2<n; ++i2)
- for (unsigned int i1=0; i1<n; ++i1)
- {
- // compute coordinates for
- // this patch point, storing in ver
- compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
+ default:
+ Assert (false, ExcNotImplemented());
}
+ for (unsigned int i=0; i<data_names.size(); ++i)
+ out << '<' << data_names[i] << "> ";
+ out << '\n';
+ }
- if (!flags.bicubic_patch)
- {
- // approximate normal
- // vectors in patch
- std::vector<Point<3> > nrml;
- // only if smooth triangles are used
- if (flags.smooth)
- {
- nrml.resize(n*n);
- // These are
- // difference
- // quotients of
- // the surface
- // mapping. We
- // take them
- // symmetric
- // inside the
- // patch and
- // one-sided at
- // the edges
- Point<3> h1,h2;
- // Now compute normals in every point
- for (unsigned int i=0; i<n; ++i)
- for (unsigned int j=0; j<n; ++j)
- {
- const unsigned int il = (i==0) ? i : (i-1);
- const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
- const unsigned int jl = (j==0) ? j : (j-1);
- const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
-
- h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
- h1(1)=patch->data(0,ir*d1+j*d2)-
- patch->data(0,il*d1+j*d2);
- h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
-
- h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
- h2(1)=patch->data(0,i*d1+jr*d2)-
- patch->data(0,i*d1+jl*d2);
- h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
-
- nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
- nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
- nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
-
- // normalize Vector
- double norm=std::sqrt(
- std::pow(nrml[i*d1+j*d2](0),2.)+
- std::pow(nrml[i*d1+j*d2](1),2.)+
- std::pow(nrml[i*d1+j*d2](2),2.));
-
- if (nrml[i*d1+j*d2](1)<0)
- norm*=-1.;
-
- for (unsigned int k=0; k<3; ++k)
- nrml[i*d1+j*d2](k)/=norm;
- }
- }
- // setting up triangles
- for (unsigned int i=0; i<n_subdivisions; ++i)
- for (unsigned int j=0; j<n_subdivisions; ++j)
+ // loop over all patches
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch != patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ // Length of loops in all dimensions
+ const unsigned int n1 = (dim>0) ? n : 1;
+ const unsigned int n2 = (dim>1) ? n : 1;
+ const unsigned int n3 = (dim>2) ? n : 1;
+ unsigned int d1 = 1;
+ unsigned int d2 = n;
+ unsigned int d3 = n*n;
+
+ Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
+ Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+ Point<spacedim> this_point;
+ Point<spacedim> node;
+ if (dim<3)
+ {
+ for (unsigned int i2=0; i2<n2; ++i2)
{
- // down/left vertex of triangle
- const int dl = i*d1+j*d2;
- if (flags.smooth)
- {
- // writing smooth_triangles
-
- // down/right triangle
- out << "smooth_triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">, <"
- << nrml[dl](0) << ", "
- << nrml[dl](1) << ", "
- << nrml[dl](2)
- << ">," << '\n';
- out << " \t<"
- << ver[dl+d1](0) << ","
- << patch->data(0,dl+d1) << ","
- << ver[dl+d1](1) << ">, <"
- << nrml[dl+d1](0) << ", "
- << nrml[dl+d1](1) << ", "
- << nrml[dl+d1](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">, <"
- << nrml[dl+d1+d2](0) << ", "
- << nrml[dl+d1+d2](1) << ", "
- << nrml[dl+d1+d2](2)
- << ">}" << '\n';
-
- // upper/left triangle
- out << "smooth_triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">, <"
- << nrml[dl](0) << ", "
- << nrml[dl](1) << ", "
- << nrml[dl](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">, <"
- << nrml[dl+d1+d2](0) << ", "
- << nrml[dl+d1+d2](1) << ", "
- << nrml[dl+d1+d2](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d2](0) << ","
- << patch->data(0,dl+d2) << ","
- << ver[dl+d2](1) << ">, <"
- << nrml[dl+d2](0) << ", "
- << nrml[dl+d2](1) << ", "
- << nrml[dl+d2](2)
- << ">}" << '\n';
- }
- else
+ for (unsigned int i1=0; i1<n1; ++i1)
{
- // writing standard triangles
- // down/right triangle
- out << "triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1](0) << ","
- << patch->data(0,dl+d1) << ","
- << ver[dl+d1](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">}" << '\n';
-
- // upper/left triangle
- out << "triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d2](0) << ","
- << patch->data(0,dl+d2) << ","
- << ver[dl+d2](1) << ">}" << '\n';
+ // compute coordinates for
+ // this patch point
+ compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
+ out << node << ' ';
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << patch->data(data_set,i1*d1+i2*d2) << ' ';
+ out << '\n';
}
+ // end of row in patch
+ if (dim>1)
+ out << '\n';
}
- }
- else
- {
- // writing bicubic_patch
- Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
- out << '\n'
- << "bicubic_patch {" << '\n'
- << " type 0" << '\n'
- << " flatness 0" << '\n'
- << " u_steps 0" << '\n'
- << " v_steps 0" << '\n';
- for (int i=0; i<16; ++i)
- {
- out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
- if (i!=15) out << ",";
+ // end of patch
+ if (dim==1)
out << '\n';
- }
- out << " texture {Tex}" << '\n'
- << "}" << '\n';
- }
- }
-
- if (!flags.bicubic_patch)
- {
- // the end of the mesh
- out << " texture {Tex}" << '\n'
- << "}" << '\n'
- << '\n';
- }
+ out << '\n';
+ }
+ else if (dim==3)
+ {
+ // for all grid points: draw
+ // lines into all positive
+ // coordinate directions if
+ // there is another grid point
+ // there
+ for (unsigned int i3=0; i3<n3; ++i3)
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ // compute coordinates for
+ // this patch point
+ compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
+ // line into positive x-direction
+ // if possible
+ if (i1 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // end of line
+ out << '\n'
+ << '\n';
+ }
+
+ // line into positive y-direction
+ // if possible
+ if (i2 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set, i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
+ out << '\n';
+
+ // end of line
+ out << '\n'
+ << '\n';
+ }
+
+ // line into positive z-direction
+ // if possible
+ if (i3 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
+ out << '\n';
+ // end of line
+ out << '\n'
+ << '\n';
+ }
- // make sure everything now gets to
- // disk
- out.flush ();
+ }
+ }
+ else
+ Assert (false, ExcNotImplemented());
+ }
+ // make sure everything now gets to
+ // disk
+ out.flush ();
- AssertThrow (out, ExcIO());
-}
+ AssertThrow (out, ExcIO());
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_eps (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &/*data_names*/,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const EpsFlags &flags,
- std::ostream &out)
-{
- Assert (out, ExcIO());
+ template <int dim, int spacedim>
+ void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const PovrayFlags &flags,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- return;
+ if (patches.size() == 0)
+ return;
#endif
+ Assert (dim==2, ExcNotImplemented()); // only for 2-D surfaces on a 2-D plane
+ Assert (spacedim==2, ExcNotImplemented());
- // Do not allow volume rendering
- AssertThrow (dim==2, ExcNotImplemented());
-
- const unsigned int old_precision = out.precision();
-
- // set up an array of cells to be
- // written later. this array holds the
- // cells of all the patches as
- // projected to the plane perpendicular
- // to the line of sight.
- //
- // note that they are kept sorted by
- // the set, where we chose the value
- // of the center point of the cell
- // along the line of sight as value
- // for sorting
- std::multiset<EpsCell2d> cells;
-
- // two variables in which we
- // will store the minimum and
- // maximum values of the field
- // to be used for colorization
- //
- // preset them by 0 to calm down the
- // compiler; they are initialized later
- double min_color_value=0, max_color_value=0;
-
- // Array for z-coordinates of points.
- // The elevation determined by a function if spacedim=2
- // or the z-cooridate of the grid point if spacedim=3
- double heights[4] = { 0, 0, 0, 0 };
-
- // compute the cells for output and
- // enter them into the set above
- // note that since dim==2, we
- // have exactly four vertices per
- // patch and per cell
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- const unsigned int d1 = 1;
- const unsigned int d2 = n;
-
- for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- Point<spacedim> points[4];
- compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
- compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
- compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
- compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
- switch (spacedim)
- {
- case 2:
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0,
- patch->data.n_rows()));
- heights[0] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
- : 0;
- heights[1] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
- : 0;
- heights[2] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
- : 0;
- heights[3] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
- : 0;
-
- break;
- case 3:
- // Copy z-coordinates into the height vector
- for (unsigned int i=0; i<4; ++i)
- heights[i] = points[i](2);
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
-
-
- // now compute the projection of
- // the bilinear cell given by the
- // four vertices and their heights
- // and write them to a proper
- // cell object. note that we only
- // need the first two components
- // of the projected position for
- // output, but we need the value
- // along the line of sight for
- // sorting the cells for back-to-
- // front-output
- //
- // this computation was first written
- // by Stefan Nauber. please no-one
- // ask me why it works that way (or
- // may be not), especially not about
- // the angles and the sign of
- // the height field, I don't know
- // it.
- EpsCell2d eps_cell;
- const double pi = numbers::PI;
- const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
- cz = -std::cos(flags.turn_angle * 2*pi / 360.),
- sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
- sz = std::sin(flags.turn_angle * 2*pi / 360.);
- for (unsigned int vertex=0; vertex<4; ++vertex)
- {
- const double x = points[vertex](0),
- y = points[vertex](1),
- z = -heights[vertex];
-
- eps_cell.vertices[vertex](0) = - cz*x+ sz*y;
- eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
-
- // ( 1 0 0 )
- // D1 = ( 0 cx -sx )
- // ( 0 sx cx )
-
- // ( cy 0 sy )
- // Dy = ( 0 1 0 )
- // (-sy 0 cy )
-
- // ( cz -sz 0 )
- // Dz = ( sz cz 0 )
- // ( 0 0 1 )
-
-// ( cz -sz 0 )( 1 0 0 )(x) ( cz*x-sz*(cx*y-sx*z)+0*(sx*y+cx*z) )
-// Dxz = ( sz cz 0 )( 0 cx -sx )(y) = ( sz*x+cz*(cx*y-sx*z)+0*(sx*y+cx*z) )
-// ( 0 0 1 )( 0 sx cx )(z) ( 0*x+ *(cx*y-sx*z)+1*(sx*y+cx*z) )
- }
+ const unsigned int n_data_sets = data_names.size();
- // compute coordinates of
- // center of cell
- const Point<spacedim> center_point
- = (points[0] + points[1] + points[2] + points[3]) / 4;
- const double center_height
- = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
+ // write preamble
+ if (true)
+ {
+ // block this to have local
+ // variables destroyed after use
+ const std::time_t time1= std::time (0);
+ const std::tm *time = std::localtime(&time1);
+ out << "/* This file was generated by the deal.II library." << '\n'
+ << " Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << " Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << '\n'
+ << " For a description of the POVRAY format see the POVRAY manual."
+ << '\n'
+ << "*/ " << '\n';
- // compute the depth into
- // the picture
- eps_cell.depth = -sx*sz*center_point(0)
- -sx*cz*center_point(1)
- +cx*center_height;
+ // include files
+ out << "#include \"colors.inc\" " << '\n'
+ << "#include \"textures.inc\" " << '\n';
- if (flags.draw_cells && flags.shade_cells)
- {
- Assert ((flags.color_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.color_vector, 0,
- patch->data.n_rows()));
- const double color_values[4]
- = { patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,i1 *d1 + i2 *d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,(i1+1)*d1 + i2 *d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,i1 *d1 + (i2+1)*d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1
- };
-
- // set color value to average of the value
- // at the vertices
- eps_cell.color_value = (color_values[0] +
- color_values[1] +
- color_values[3] +
- color_values[2]) / 4;
-
- // update bounds of color
- // field
- if (patch == patches.begin())
- min_color_value = max_color_value = eps_cell.color_value;
- else
- {
- min_color_value = (min_color_value < eps_cell.color_value ?
- min_color_value : eps_cell.color_value);
- max_color_value = (max_color_value > eps_cell.color_value ?
- max_color_value : eps_cell.color_value);
- }
- }
- // finally add this cell
- cells.insert (eps_cell);
+ // use external include file for textures,
+ // camera and light
+ if (flags.external_data)
+ out << "#include \"data.inc\" " << '\n';
+ else // all definitions in data file
+ {
+ // camera
+ out << '\n' << '\n'
+ << "camera {" << '\n'
+ << " location <1,4,-7>" << '\n'
+ << " look_at <0,0,0>" << '\n'
+ << " angle 30" << '\n'
+ << "}" << '\n';
+
+ // light
+ out << '\n'
+ << "light_source {" << '\n'
+ << " <1,4,-7>" << '\n'
+ << " color Grey" << '\n'
+ << "}" << '\n';
+ out << '\n'
+ << "light_source {" << '\n'
+ << " <0,20,0>" << '\n'
+ << " color White" << '\n'
+ << "}" << '\n';
}
- }
-
- // find out minimum and maximum x and
- // y coordinates to compute offsets
- // and scaling factors
- double x_min = cells.begin()->vertices[0](0);
- double x_max = x_min;
- double y_min = cells.begin()->vertices[0](1);
- double y_max = y_min;
-
- for (typename std::multiset<EpsCell2d>::const_iterator
- cell=cells.begin();
- cell!=cells.end(); ++cell)
- for (unsigned int vertex=0; vertex<4; ++vertex)
- {
- x_min = std::min (x_min, cell->vertices[vertex](0));
- x_max = std::max (x_max, cell->vertices[vertex](0));
- y_min = std::min (y_min, cell->vertices[vertex](1));
- y_max = std::max (y_max, cell->vertices[vertex](1));
}
- // scale in x-direction such that
- // in the output 0 <= x <= 300.
- // don't scale in y-direction to
- // preserve the shape of the
- // triangulation
- const double scale = (flags.size /
- (flags.size_type==EpsFlags::width ?
- x_max - x_min :
- y_min - y_max));
-
- const Point<2> offset(x_min, y_min);
+ // max. and min. heigth of solution
+ typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ Assert(patch!=patches.end(), ExcInternalError());
+ double hmin=patch->data(0,0);
+ double hmax=patch->data(0,0);
+ for (; patch != patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+
+ Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
+ Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ {
+ const int dl = i*(n_subdivisions+1)+j;
+ if (patch->data(0,dl)<hmin)
+ hmin=patch->data(0,dl);
+ if (patch->data(0,dl)>hmax)
+ hmax=patch->data(0,dl);
+ }
+ }
- // now write preamble
- if (true)
- {
- // block this to have local
- // variables destroyed after
- // use
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
- << "%%Title: deal.II Output" << '\n'
- << "%%Creator: the deal.II library" << '\n'
- << "%%Creation Date: "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " - "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "%%BoundingBox: "
- // lower left corner
- << "0 0 "
- // upper right corner
- << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
- << ' '
- << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
- << '\n';
-
- // define some abbreviations to keep
- // the output small:
- // m=move turtle to
- // l=define a line
- // s=set rgb color
- // sg=set gray value
- // lx=close the line and plot the line
- // lf=close the line and fill the interior
- out << "/m {moveto} bind def" << '\n'
- << "/l {lineto} bind def" << '\n'
- << "/s {setrgbcolor} bind def" << '\n'
- << "/sg {setgray} bind def" << '\n'
- << "/lx {lineto closepath stroke} bind def" << '\n'
- << "/lf {lineto closepath fill} bind def" << '\n';
-
- out << "%%EndProlog" << '\n'
- << '\n';
- // set fine lines
- out << flags.line_width << " setlinewidth" << '\n';
- // allow only five digits
- // for output (instead of the
- // default six); this should suffice
- // even for fine grids, but reduces
- // the file size significantly
- out << std::setprecision (5);
- }
+ out << "#declare HMIN=" << hmin << ";" << '\n'
+ << "#declare HMAX=" << hmax << ";" << '\n' << '\n';
- // check if min and max
- // values for the color are
- // actually different. If
- // that is not the case (such
- // things happen, for
- // example, in the very first
- // time step of a time
- // dependent problem, if the
- // initial values are zero),
- // all values are equal, and
- // then we can draw
- // everything in an arbitrary
- // color. Thus, change one of
- // the two values arbitrarily
- if (max_color_value == min_color_value)
- max_color_value = min_color_value+1;
-
- // now we've got all the information
- // we need. write the cells.
- // note: due to the ordering, we
- // traverse the list of cells
- // back-to-front
- for (typename std::multiset<EpsCell2d>::const_iterator
- cell=cells.begin();
- cell!=cells.end(); ++cell)
- {
- if (flags.draw_cells)
- {
- if (flags.shade_cells)
+ if (!flags.external_data)
+ {
+ // texture with scaled niveau lines
+ // 10 lines in the surface
+ out << "#declare Tex=texture{" << '\n'
+ << " pigment {" << '\n'
+ << " gradient y" << '\n'
+ << " scale y*(HMAX-HMIN)*" << 0.1 << '\n'
+ << " color_map {" << '\n'
+ << " [0.00 color Light_Purple] " << '\n'
+ << " [0.95 color Light_Purple] " << '\n'
+ << " [1.00 color White] " << '\n'
+ << "} } }" << '\n' << '\n';
+ }
+
+ if (!flags.bicubic_patch)
+ {
+ // start of mesh header
+ out << '\n'
+ << "mesh {" << '\n';
+ }
+
+ // loop over all patches
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch != patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ const unsigned int d1=1;
+ const unsigned int d2=n;
+
+ Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
+ Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+
+ std::vector<Point<spacedim> > ver(n*n);
+
+ for (unsigned int i2=0; i2<n; ++i2)
+ for (unsigned int i1=0; i1<n; ++i1)
{
- const EpsFlags::RgbValues rgb_values
- = (*flags.color_function) (cell->color_value,
- min_color_value,
- max_color_value);
-
- // write out color
- if (rgb_values.is_grey())
- out << rgb_values.red << " sg ";
- else
- out << rgb_values.red << ' '
- << rgb_values.green << ' '
- << rgb_values.blue << " s ";
+ // compute coordinates for
+ // this patch point, storing in ver
+ compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
}
- else
- out << "1 sg ";
- out << (cell->vertices[0]-offset) * scale << " m "
- << (cell->vertices[1]-offset) * scale << " l "
- << (cell->vertices[3]-offset) * scale << " l "
- << (cell->vertices[2]-offset) * scale << " lf"
- << '\n';
- }
- if (flags.draw_mesh)
- out << "0 sg " // draw lines in black
- << (cell->vertices[0]-offset) * scale << " m "
- << (cell->vertices[1]-offset) * scale << " l "
- << (cell->vertices[3]-offset) * scale << " l "
- << (cell->vertices[2]-offset) * scale << " lx"
+ if (!flags.bicubic_patch)
+ {
+ // approximate normal
+ // vectors in patch
+ std::vector<Point<3> > nrml;
+ // only if smooth triangles are used
+ if (flags.smooth)
+ {
+ nrml.resize(n*n);
+ // These are
+ // difference
+ // quotients of
+ // the surface
+ // mapping. We
+ // take them
+ // symmetric
+ // inside the
+ // patch and
+ // one-sided at
+ // the edges
+ Point<3> h1,h2;
+ // Now compute normals in every point
+ for (unsigned int i=0; i<n; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ {
+ const unsigned int il = (i==0) ? i : (i-1);
+ const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
+ const unsigned int jl = (j==0) ? j : (j-1);
+ const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
+
+ h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
+ h1(1)=patch->data(0,ir*d1+j*d2)-
+ patch->data(0,il*d1+j*d2);
+ h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
+
+ h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
+ h2(1)=patch->data(0,i*d1+jr*d2)-
+ patch->data(0,i*d1+jl*d2);
+ h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
+
+ nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
+ nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
+ nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
+
+ // normalize Vector
+ double norm=std::sqrt(
+ std::pow(nrml[i*d1+j*d2](0),2.)+
+ std::pow(nrml[i*d1+j*d2](1),2.)+
+ std::pow(nrml[i*d1+j*d2](2),2.));
+
+ if (nrml[i*d1+j*d2](1)<0)
+ norm*=-1.;
+
+ for (unsigned int k=0; k<3; ++k)
+ nrml[i*d1+j*d2](k)/=norm;
+ }
+ }
+
+ // setting up triangles
+ for (unsigned int i=0; i<n_subdivisions; ++i)
+ for (unsigned int j=0; j<n_subdivisions; ++j)
+ {
+ // down/left vertex of triangle
+ const int dl = i*d1+j*d2;
+ if (flags.smooth)
+ {
+ // writing smooth_triangles
+
+ // down/right triangle
+ out << "smooth_triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">, <"
+ << nrml[dl](0) << ", "
+ << nrml[dl](1) << ", "
+ << nrml[dl](2)
+ << ">," << '\n';
+ out << " \t<"
+ << ver[dl+d1](0) << ","
+ << patch->data(0,dl+d1) << ","
+ << ver[dl+d1](1) << ">, <"
+ << nrml[dl+d1](0) << ", "
+ << nrml[dl+d1](1) << ", "
+ << nrml[dl+d1](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">, <"
+ << nrml[dl+d1+d2](0) << ", "
+ << nrml[dl+d1+d2](1) << ", "
+ << nrml[dl+d1+d2](2)
+ << ">}" << '\n';
+
+ // upper/left triangle
+ out << "smooth_triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">, <"
+ << nrml[dl](0) << ", "
+ << nrml[dl](1) << ", "
+ << nrml[dl](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">, <"
+ << nrml[dl+d1+d2](0) << ", "
+ << nrml[dl+d1+d2](1) << ", "
+ << nrml[dl+d1+d2](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d2](0) << ","
+ << patch->data(0,dl+d2) << ","
+ << ver[dl+d2](1) << ">, <"
+ << nrml[dl+d2](0) << ", "
+ << nrml[dl+d2](1) << ", "
+ << nrml[dl+d2](2)
+ << ">}" << '\n';
+ }
+ else
+ {
+ // writing standard triangles
+ // down/right triangle
+ out << "triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1](0) << ","
+ << patch->data(0,dl+d1) << ","
+ << ver[dl+d1](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">}" << '\n';
+
+ // upper/left triangle
+ out << "triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d2](0) << ","
+ << patch->data(0,dl+d2) << ","
+ << ver[dl+d2](1) << ">}" << '\n';
+ }
+ }
+ }
+ else
+ {
+ // writing bicubic_patch
+ Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
+ out << '\n'
+ << "bicubic_patch {" << '\n'
+ << " type 0" << '\n'
+ << " flatness 0" << '\n'
+ << " u_steps 0" << '\n'
+ << " v_steps 0" << '\n';
+ for (int i=0; i<16; ++i)
+ {
+ out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
+ if (i!=15) out << ",";
+ out << '\n';
+ }
+ out << " texture {Tex}" << '\n'
+ << "}" << '\n';
+ }
+ }
+
+ if (!flags.bicubic_patch)
+ {
+ // the end of the mesh
+ out << " texture {Tex}" << '\n'
+ << "}" << '\n'
<< '\n';
- }
- out << "showpage" << '\n';
- // make sure everything now gets to
- // disk
- out << std::setprecision(old_precision);
- out.flush ();
+ }
- AssertThrow (out, ExcIO());
-}
+ // make sure everything now gets to
+ // disk
+ out.flush ();
+ AssertThrow (out, ExcIO());
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const GmvFlags &flags,
- std::ostream &out)
-{
- Assert(dim<=3, ExcNotImplemented());
- AssertThrow (out, ExcIO());
+
+ template <int dim, int spacedim>
+ void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &/*data_names*/,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const EpsFlags &flags,
+ std::ostream &out)
+ {
+ Assert (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- return;
+ if (patches.size() == 0)
+ return;
#endif
- GmvStream gmv_out(out, flags);
- const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
- Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- ///////////////////////
- // preamble
- out << "gmvinput ascii"
- << '\n'
- << '\n';
-
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
- Table<2,double> data_vectors (n_data_sets, n_nodes);
- void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
- = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
- Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that we have to print
- // 3 dimensions
- out << "nodes " << n_nodes << '\n';
- for (unsigned int d=0; d<spacedim; ++d)
- {
- gmv_out.selected_component = d;
- write_nodes(patches, gmv_out);
- out << '\n';
- }
- gmv_out.selected_component = numbers::invalid_unsigned_int;
-
- for (unsigned int d=spacedim; d<3; ++d)
- {
- for (unsigned int i=0; i<n_nodes; ++i)
- out << "0 ";
- out << '\n';
- }
-
- /////////////////////////////////
- // now for the cells. note that
- // vertices are counted from 1 onwards
- out << "cells " << n_cells << '\n';
- write_cells(patches, gmv_out);
+ // Do not allow volume rendering
+ AssertThrow (dim==2, ExcNotImplemented());
+
+ const unsigned int old_precision = out.precision();
+
+ // set up an array of cells to be
+ // written later. this array holds the
+ // cells of all the patches as
+ // projected to the plane perpendicular
+ // to the line of sight.
+ //
+ // note that they are kept sorted by
+ // the set, where we chose the value
+ // of the center point of the cell
+ // along the line of sight as value
+ // for sorting
+ std::multiset<EpsCell2d> cells;
+
+ // two variables in which we
+ // will store the minimum and
+ // maximum values of the field
+ // to be used for colorization
+ //
+ // preset them by 0 to calm down the
+ // compiler; they are initialized later
+ double min_color_value=0, max_color_value=0;
+
+ // Array for z-coordinates of points.
+ // The elevation determined by a function if spacedim=2
+ // or the z-cooridate of the grid point if spacedim=3
+ double heights[4] = { 0, 0, 0, 0 };
+
+ // compute the cells for output and
+ // enter them into the set above
+ // note that since dim==2, we
+ // have exactly four vertices per
+ // patch and per cell
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ const unsigned int d1 = 1;
+ const unsigned int d2 = n;
- ///////////////////////////////////////
- // data output.
- out << "variable" << '\n';
+ for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ Point<spacedim> points[4];
+ compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
+ compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
+ compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
+ compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
- reorder_task.join ();
+ switch (spacedim)
+ {
+ case 2:
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0,
+ patch->data.n_rows()));
+ heights[0] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
+ : 0;
+ heights[1] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
+ : 0;
+ heights[2] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
+ : 0;
+ heights[3] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
+ : 0;
+
+ break;
+ case 3:
+ // Copy z-coordinates into the height vector
+ for (unsigned int i=0; i<4; ++i)
+ heights[i] = points[i](2);
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
- // then write data.
- // the '1' means: node data (as opposed
- // to cell data, which we do not
- // support explicitly here)
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- {
- out << data_names[data_set] << " 1" << '\n';
- std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, " "));
- out << '\n'
- << '\n';
- }
+ // now compute the projection of
+ // the bilinear cell given by the
+ // four vertices and their heights
+ // and write them to a proper
+ // cell object. note that we only
+ // need the first two components
+ // of the projected position for
+ // output, but we need the value
+ // along the line of sight for
+ // sorting the cells for back-to-
+ // front-output
+ //
+ // this computation was first written
+ // by Stefan Nauber. please no-one
+ // ask me why it works that way (or
+ // may be not), especially not about
+ // the angles and the sign of
+ // the height field, I don't know
+ // it.
+ EpsCell2d eps_cell;
+ const double pi = numbers::PI;
+ const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
+ cz = -std::cos(flags.turn_angle * 2*pi / 360.),
+ sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
+ sz = std::sin(flags.turn_angle * 2*pi / 360.);
+ for (unsigned int vertex=0; vertex<4; ++vertex)
+ {
+ const double x = points[vertex](0),
+ y = points[vertex](1),
+ z = -heights[vertex];
+ eps_cell.vertices[vertex](0) = - cz*x+ sz*y;
+ eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
- // end of variable section
- out << "endvars" << '\n';
+ // ( 1 0 0 )
+ // D1 = ( 0 cx -sx )
+ // ( 0 sx cx )
- // end of output
- out << "endgmv"
- << '\n';
+ // ( cy 0 sy )
+ // Dy = ( 0 1 0 )
+ // (-sy 0 cy )
- // make sure everything now gets to
- // disk
- out.flush ();
+ // ( cz -sz 0 )
+ // Dz = ( sz cz 0 )
+ // ( 0 0 1 )
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+// ( cz -sz 0 )( 1 0 0 )(x) ( cz*x-sz*(cx*y-sx*z)+0*(sx*y+cx*z) )
+// Dxz = ( sz cz 0 )( 0 cx -sx )(y) = ( sz*x+cz*(cx*y-sx*z)+0*(sx*y+cx*z) )
+// ( 0 0 1 )( 0 sx cx )(z) ( 0*x+ *(cx*y-sx*z)+1*(sx*y+cx*z) )
+ }
+ // compute coordinates of
+ // center of cell
+ const Point<spacedim> center_point
+ = (points[0] + points[1] + points[2] + points[3]) / 4;
+ const double center_height
+ = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
+ // compute the depth into
+ // the picture
+ eps_cell.depth = -sx*sz*center_point(0)
+ -sx*cz*center_point(1)
+ +cx*center_height;
-template <int dim, int spacedim>
-void DataOutBase::write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const TecplotFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ if (flags.draw_cells && flags.shade_cells)
+ {
+ Assert ((flags.color_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.color_vector, 0,
+ patch->data.n_rows()));
+ const double color_values[4]
+ = { patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,i1 *d1 + i2 *d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,(i1+1)*d1 + i2 *d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,i1 *d1 + (i2+1)*d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1
+ };
+
+ // set color value to average of the value
+ // at the vertices
+ eps_cell.color_value = (color_values[0] +
+ color_values[1] +
+ color_values[3] +
+ color_values[2]) / 4;
+
+ // update bounds of color
+ // field
+ if (patch == patches.begin())
+ min_color_value = max_color_value = eps_cell.color_value;
+ else
+ {
+ min_color_value = (min_color_value < eps_cell.color_value ?
+ min_color_value : eps_cell.color_value);
+ max_color_value = (max_color_value > eps_cell.color_value ?
+ max_color_value : eps_cell.color_value);
+ }
+ }
-#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
-#else
- if (patches.size() == 0)
- return;
-#endif
+ // finally add this cell
+ cells.insert (eps_cell);
+ }
+ }
- TecplotStream tecplot_out(out, flags);
+ // find out minimum and maximum x and
+ // y coordinates to compute offsets
+ // and scaling factors
+ double x_min = cells.begin()->vertices[0](0);
+ double x_max = x_min;
+ double y_min = cells.begin()->vertices[0](1);
+ double y_max = y_min;
+
+ for (typename std::multiset<EpsCell2d>::const_iterator
+ cell=cells.begin();
+ cell!=cells.end(); ++cell)
+ for (unsigned int vertex=0; vertex<4; ++vertex)
+ {
+ x_min = std::min (x_min, cell->vertices[vertex](0));
+ x_max = std::max (x_max, cell->vertices[vertex](0));
+ y_min = std::min (y_min, cell->vertices[vertex](1));
+ y_max = std::max (y_max, cell->vertices[vertex](1));
+ }
- const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
- Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-
- ///////////
- // preamble
- {
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the Tecplot format see the Tecplot documentation."
- << '\n'
- << "#" << '\n';
+ // scale in x-direction such that
+ // in the output 0 <= x <= 300.
+ // don't scale in y-direction to
+ // preserve the shape of the
+ // triangulation
+ const double scale = (flags.size /
+ (flags.size_type==EpsFlags::width ?
+ x_max - x_min :
+ y_min - y_max));
+ const Point<2> offset(x_min, y_min);
- out << "Variables=";
- switch (spacedim)
+ // now write preamble
+ if (true)
{
- case 1:
- out << "\"x\"";
- break;
- case 2:
- out << "\"x\", \"y\"";
- break;
- case 3:
- out << "\"x\", \"y\", \"z\"";
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
+ // block this to have local
+ // variables destroyed after
+ // use
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
+ << "%%Title: deal.II Output" << '\n'
+ << "%%Creator: the deal.II library" << '\n'
+ << "%%Creation Date: "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " - "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "%%BoundingBox: "
+ // lower left corner
+ << "0 0 "
+ // upper right corner
+ << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
+ << ' '
+ << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
+ << '\n';
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ", \"" << data_names[data_set] << "\"";
+ // define some abbreviations to keep
+ // the output small:
+ // m=move turtle to
+ // l=define a line
+ // s=set rgb color
+ // sg=set gray value
+ // lx=close the line and plot the line
+ // lf=close the line and fill the interior
+ out << "/m {moveto} bind def" << '\n'
+ << "/l {lineto} bind def" << '\n'
+ << "/s {setrgbcolor} bind def" << '\n'
+ << "/sg {setgray} bind def" << '\n'
+ << "/lx {lineto closepath stroke} bind def" << '\n'
+ << "/lf {lineto closepath fill} bind def" << '\n';
+
+ out << "%%EndProlog" << '\n'
+ << '\n';
+ // set fine lines
+ out << flags.line_width << " setlinewidth" << '\n';
+ // allow only five digits
+ // for output (instead of the
+ // default six); this should suffice
+ // even for fine grids, but reduces
+ // the file size significantly
+ out << std::setprecision (5);
+ }
- out << '\n';
+ // check if min and max
+ // values for the color are
+ // actually different. If
+ // that is not the case (such
+ // things happen, for
+ // example, in the very first
+ // time step of a time
+ // dependent problem, if the
+ // initial values are zero),
+ // all values are equal, and
+ // then we can draw
+ // everything in an arbitrary
+ // color. Thus, change one of
+ // the two values arbitrarily
+ if (max_color_value == min_color_value)
+ max_color_value = min_color_value+1;
+
+ // now we've got all the information
+ // we need. write the cells.
+ // note: due to the ordering, we
+ // traverse the list of cells
+ // back-to-front
+ for (typename std::multiset<EpsCell2d>::const_iterator
+ cell=cells.begin();
+ cell!=cells.end(); ++cell)
+ {
+ if (flags.draw_cells)
+ {
+ if (flags.shade_cells)
+ {
+ const EpsFlags::RgbValues rgb_values
+ = (*flags.color_function) (cell->color_value,
+ min_color_value,
+ max_color_value);
+
+ // write out color
+ if (rgb_values.is_grey())
+ out << rgb_values.red << " sg ";
+ else
+ out << rgb_values.red << ' '
+ << rgb_values.green << ' '
+ << rgb_values.blue << " s ";
+ }
+ else
+ out << "1 sg ";
+
+ out << (cell->vertices[0]-offset) * scale << " m "
+ << (cell->vertices[1]-offset) * scale << " l "
+ << (cell->vertices[3]-offset) * scale << " l "
+ << (cell->vertices[2]-offset) * scale << " lf"
+ << '\n';
+ }
- out << "zone ";
- if (flags.zone_name)
- out << "t=\"" << flags.zone_name << "\" ";
+ if (flags.draw_mesh)
+ out << "0 sg " // draw lines in black
+ << (cell->vertices[0]-offset) * scale << " m "
+ << (cell->vertices[1]-offset) * scale << " l "
+ << (cell->vertices[3]-offset) * scale << " l "
+ << (cell->vertices[2]-offset) * scale << " lx"
+ << '\n';
+ }
+ out << "showpage" << '\n';
+ // make sure everything now gets to
+ // disk
+ out << std::setprecision(old_precision);
+ out.flush ();
- out << "f=feblock, n=" << n_nodes << ", e=" << n_cells
- << ", et=" << tecplot_cell_type[dim] << '\n';
+ AssertThrow (out, ExcIO());
}
- // in Tecplot FEBLOCK format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
-
- Table<2,double> data_vectors (n_data_sets, n_nodes);
- void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
- = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
- Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+ template <int dim, int spacedim>
+ void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const GmvFlags &flags,
+ std::ostream &out)
+ {
+ Assert(dim<=3, ExcNotImplemented());
+ AssertThrow (out, ExcIO());
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
+#ifndef DEAL_II_WITH_MPI
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
+#else
+ if (patches.size() == 0)
+ return;
+#endif
+ GmvStream gmv_out(out, flags);
+ const unsigned int n_data_sets = data_names.size();
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
+ Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ ///////////////////////
+ // preamble
+ out << "gmvinput ascii"
+ << '\n'
+ << '\n';
- for (unsigned int d=0; d<spacedim; ++d)
- {
- tecplot_out.selected_component = d;
- write_nodes(patches, tecplot_out);
- out << '\n';
- }
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
+ Table<2,double> data_vectors (n_data_sets, n_nodes);
+ void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+ Table<2,double> &)
+ = &write_gmv_reorder_data_vectors<dim,spacedim>;
+ Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that we have to print
+ // 3 dimensions
+ out << "nodes " << n_nodes << '\n';
+ for (unsigned int d=0; d<spacedim; ++d)
+ {
+ gmv_out.selected_component = d;
+ write_nodes(patches, gmv_out);
+ out << '\n';
+ }
+ gmv_out.selected_component = numbers::invalid_unsigned_int;
+ for (unsigned int d=spacedim; d<3; ++d)
+ {
+ for (unsigned int i=0; i<n_nodes; ++i)
+ out << "0 ";
+ out << '\n';
+ }
- ///////////////////////////////////////
- // data output.
- //
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
- reorder_task.join ();
+ /////////////////////////////////
+ // now for the cells. note that
+ // vertices are counted from 1 onwards
+ out << "cells " << n_cells << '\n';
+ write_cells(patches, gmv_out);
+
+ ///////////////////////////////////////
+ // data output.
+ out << "variable" << '\n';
+
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
+ reorder_task.join ();
+
+ // then write data.
+ // the '1' means: node data (as opposed
+ // to cell data, which we do not
+ // support explicitly here)
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ {
+ out << data_names[data_set] << " 1" << '\n';
+ std::copy (data_vectors[data_set].begin(),
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, " "));
+ out << '\n'
+ << '\n';
+ }
- // then write data.
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- {
- std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, "\n"));
- out << '\n';
- }
- write_cells(patches, tecplot_out);
- // make sure everything now gets to
- // disk
- out.flush ();
+ // end of variable section
+ out << "endvars" << '\n';
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+ // end of output
+ out << "endgmv"
+ << '\n';
+ // make sure everything now gets to
+ // disk
+ out.flush ();
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
-//---------------------------------------------------------------------------
-// Macros for handling Tecplot API data
-#ifdef DEAL_II_HAVE_TECPLOT
-namespace
-{
- class TecplotMacros
+ template <int dim, int spacedim>
+ void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const TecplotFlags &flags,
+ std::ostream &out)
{
- public:
- TecplotMacros(const unsigned int n_nodes = 0,
- const unsigned int n_vars = 0,
- const unsigned int n_cells = 0,
- const unsigned int n_vert = 0);
- ~TecplotMacros();
- float &nd(const unsigned int i, const unsigned int j);
- int &cd(const unsigned int i, const unsigned int j);
- std::vector<float> nodalData;
- std::vector<int> connData;
- private:
- unsigned int n_nodes;
- unsigned int n_vars;
- unsigned int n_cells;
- unsigned int n_vert;
- };
+ AssertThrow (out, ExcIO());
+#ifndef DEAL_II_WITH_MPI
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
+#else
+ if (patches.size() == 0)
+ return;
+#endif
- inline
- TecplotMacros::TecplotMacros(const unsigned int n_nodes,
- const unsigned int n_vars,
- const unsigned int n_cells,
- const unsigned int n_vert)
- :
- n_nodes(n_nodes),
- n_vars(n_vars),
- n_cells(n_cells),
- n_vert(n_vert)
- {
- nodalData.resize(n_nodes*n_vars);
- connData.resize(n_cells*n_vert);
- }
+ TecplotStream tecplot_out(out, flags);
+
+ const unsigned int n_data_sets = data_names.size();
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
+ Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+ ///////////
+ // preamble
+ {
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "# This file was generated by the deal.II library." << '\n'
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the Tecplot format see the Tecplot documentation."
+ << '\n'
+ << "#" << '\n';
- inline
- TecplotMacros::~TecplotMacros()
- {}
+ out << "Variables=";
+ switch (spacedim)
+ {
+ case 1:
+ out << "\"x\"";
+ break;
+ case 2:
+ out << "\"x\", \"y\"";
+ break;
+ case 3:
+ out << "\"x\", \"y\", \"z\"";
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ", \"" << data_names[data_set] << "\"";
- inline
- float &TecplotMacros::nd (const unsigned int i,
- const unsigned int j)
- {
- return nodalData[i*n_nodes+j];
- }
+ out << '\n';
+ out << "zone ";
+ if (flags.zone_name)
+ out << "t=\"" << flags.zone_name << "\" ";
+ out << "f=feblock, n=" << n_nodes << ", e=" << n_cells
+ << ", et=" << tecplot_cell_type[dim] << '\n';
+ }
- inline
- int &TecplotMacros::cd (const unsigned int i,
- const unsigned int j)
- {
- return connData[i+j*n_vert];
- }
-}
+ // in Tecplot FEBLOCK format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
+
+ Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+ void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+ Table<2,double> &)
+ = &write_gmv_reorder_data_vectors<dim,spacedim>;
+ Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+
+
+ for (unsigned int d=0; d<spacedim; ++d)
+ {
+ tecplot_out.selected_component = d;
+ write_nodes(patches, tecplot_out);
+ out << '\n';
+ }
-#endif
-//---------------------------------------------------------------------------
+ ///////////////////////////////////////
+ // data output.
+ //
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
+ reorder_task.join ();
+ // then write data.
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ {
+ std::copy (data_vectors[data_set].begin(),
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, "\n"));
+ out << '\n';
+ }
+ write_cells(patches, tecplot_out);
-template <int dim, int spacedim>
-void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const TecplotFlags &flags,
- std::ostream &out)
-{
+ // make sure everything now gets to
+ // disk
+ out.flush ();
-#ifndef DEAL_II_HAVE_TECPLOT
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
- // simply call the ASCII output
- // function if the Tecplot API
- // isn't present
- write_tecplot (patches, data_names, vector_data_ranges, flags, out);
- return;
-#else
- // Tecplot binary output only good
- // for 2D & 3D
- if (dim == 1)
- {
- write_tecplot (patches, data_names, vector_data_ranges, flags, out);
- return;
- }
+//---------------------------------------------------------------------------
+// Macros for handling Tecplot API data
- // if the user hasn't specified a
- // file name we should call the
- // ASCII function and use the
- // ostream @p{out} instead of doing
- // something silly later
- char *file_name = (char *) flags.tecplot_binary_file_name;
+#ifdef DEAL_II_HAVE_TECPLOT
- if (file_name == NULL)
+ namespace
+ {
+ class TecplotMacros
{
- // At least in debug mode we
- // should tell users why they
- // don't get tecplot binary
- // output
- Assert(false, ExcMessage("Specify the name of the tecplot_binary"
- " file through the TecplotFlags interface."));
- write_tecplot (patches, data_names, vector_data_ranges, flags, out);
- return;
- }
-
-
- AssertThrow (out, ExcIO());
+ public:
+ TecplotMacros(const unsigned int n_nodes = 0,
+ const unsigned int n_vars = 0,
+ const unsigned int n_cells = 0,
+ const unsigned int n_vert = 0);
+ ~TecplotMacros();
+ float &nd(const unsigned int i, const unsigned int j);
+ int &cd(const unsigned int i, const unsigned int j);
+ std::vector<float> nodalData;
+ std::vector<int> connData;
+ private:
+ unsigned int n_nodes;
+ unsigned int n_vars;
+ unsigned int n_cells;
+ unsigned int n_vert;
+ };
-#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
-#else
- if (patches.size() == 0)
- return;
-#endif
- const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
- Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // local variables only needed to write Tecplot
- // binary output files
- const unsigned int vars_per_node = (spacedim+n_data_sets),
- nodes_per_cell = GeometryInfo<dim>::vertices_per_cell;
-
- TecplotMacros tm(n_nodes, vars_per_node, n_cells, nodes_per_cell);
-
- int is_double = 0,
- tec_debug = 0,
- cell_type = tecplot_binary_cell_type[dim];
-
- std::string tec_var_names;
- switch (spacedim)
+ inline
+ TecplotMacros::TecplotMacros(const unsigned int n_nodes,
+ const unsigned int n_vars,
+ const unsigned int n_cells,
+ const unsigned int n_vert)
+ :
+ n_nodes(n_nodes),
+ n_vars(n_vars),
+ n_cells(n_cells),
+ n_vert(n_vert)
{
- case 2:
- tec_var_names = "x y";
- break;
- case 3:
- tec_var_names = "x y z";
- break;
- default:
- Assert(false, ExcNotImplemented());
+ nodalData.resize(n_nodes*n_vars);
+ connData.resize(n_cells*n_vert);
}
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- {
- tec_var_names += " ";
- tec_var_names += data_names[data_set];
- }
- // in Tecplot FEBLOCK format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
- Table<2,double> data_vectors (n_data_sets, n_nodes);
-
- void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
- = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
- Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- for (unsigned int d=1; d<=spacedim; ++d)
- {
- unsigned int entry=0;
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- switch (dim)
- {
- case 2:
- {
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- {
- const double x_frac = i * 1./n_subdivisions,
- y_frac = j * 1./n_subdivisions;
-
- tm.nd((d-1),entry) = static_cast<float>(
- (((patch->vertices[1](d-1) * x_frac) +
- (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[3](d-1) * x_frac) +
- (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
- );
- entry++;
- }
- break;
- }
+ inline
+ TecplotMacros::~TecplotMacros()
+ {}
- case 3:
- {
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
- for (unsigned int k=0; k<n_subdivisions+1; ++k)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- {
- const double x_frac = i * 1./n_subdivisions,
- y_frac = k * 1./n_subdivisions,
- z_frac = j * 1./n_subdivisions;
- // compute coordinates for
- // this patch point
- tm.nd((d-1),entry) = static_cast<float>(
- ((((patch->vertices[1](d-1) * x_frac) +
- (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[3](d-1) * x_frac) +
- (patch->vertices[2](d-1) * (1-x_frac))) * y_frac) * (1-z_frac) +
- (((patch->vertices[5](d-1) * x_frac) +
- (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[7](d-1) * x_frac) +
- (patch->vertices[6](d-1) * (1-x_frac))) * y_frac) * z_frac)
- );
- entry++;
- }
- break;
- }
- default:
- Assert (false, ExcNotImplemented());
- }
- }
+ inline
+ float &TecplotMacros::nd (const unsigned int i,
+ const unsigned int j)
+ {
+ return nodalData[i*n_nodes+j];
}
- ///////////////////////////////////////
- // data output.
- //
- reorder_task.join ();
- // then write data.
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- for (unsigned int entry=0; entry<data_vectors[data_set].size(); entry++)
- tm.nd((spacedim+data_set),entry) = static_cast<float>(data_vectors[data_set][entry]);
+ inline
+ int &TecplotMacros::cd (const unsigned int i,
+ const unsigned int j)
+ {
+ return connData[i+j*n_vert];
+ }
+ }
+#endif
+//---------------------------------------------------------------------------
- /////////////////////////////////
- // now for the cells. note that
- // vertices are counted from 1 onwards
- unsigned int first_vertex_of_patch = 0;
- unsigned int elem=0;
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
- const unsigned int n = n_subdivisions+1;
- const unsigned int d1=1;
- const unsigned int d2=n;
- const unsigned int d3=n*n;
- // write out the cells making
- // up this patch
- switch (dim)
- {
- case 2:
- {
- for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+1;
- tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+1;
- tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
- tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+1;
- elem++;
- }
- break;
- }
+ template <int dim, int spacedim>
+ void write_tecplot_binary (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const TecplotFlags &flags,
+ std::ostream &out)
+ {
- case 3:
- {
- for (unsigned int i3=0; i3<n_subdivisions; ++i3)
- for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- // note: vertex indices start with 1!
+#ifndef DEAL_II_HAVE_TECPLOT
+ // simply call the ASCII output
+ // function if the Tecplot API
+ // isn't present
+ write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+ return;
- tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3 )*d3+1;
- tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3 )*d3+1;
- tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3 )*d3+1;
- tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3 )*d3+1;
- tm.cd(4,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3+1)*d3+1;
- tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3+1)*d3+1;
- tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
- tm.cd(7,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3+1)*d3+1;
+#else
- elem++;
- }
- break;
- }
+ // Tecplot binary output only good
+ // for 2D & 3D
+ if (dim == 1)
+ {
+ write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+ return;
+ }
- default:
- Assert (false, ExcNotImplemented());
- }
+ // if the user hasn't specified a
+ // file name we should call the
+ // ASCII function and use the
+ // ostream @p{out} instead of doing
+ // something silly later
+ char *file_name = (char *) flags.tecplot_binary_file_name;
+ if (file_name == NULL)
+ {
+ // At least in debug mode we
+ // should tell users why they
+ // don't get tecplot binary
+ // output
+ Assert(false, ExcMessage("Specify the name of the tecplot_binary"
+ " file through the TecplotFlags interface."));
+ write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+ return;
+ }
- // finally update the number
- // of the first vertex of this patch
- first_vertex_of_patch += Utilities::fixed_power<dim>(n);
- }
+ AssertThrow (out, ExcIO());
- {
- int ierr = 0,
- num_nodes = static_cast<int>(n_nodes),
- num_cells = static_cast<int>(n_cells);
+#ifndef DEAL_II_WITH_MPI
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
+#else
+ if (patches.size() == 0)
+ return;
+#endif
- char dot[2] = {'.', 0};
- // Unfortunately, TECINI takes a
- // char *, but c_str() gives a
- // const char *. As we don't do
- // anything else with
- // tec_var_names following
- // const_cast is ok
- char *var_names=const_cast<char *> (tec_var_names.c_str());
- ierr = TECINI (NULL,
- var_names,
- file_name,
- dot,
- &tec_debug,
- &is_double);
+ const unsigned int n_data_sets = data_names.size();
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
+ Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+ // local variables only needed to write Tecplot
+ // binary output files
+ const unsigned int vars_per_node = (spacedim+n_data_sets),
+ nodes_per_cell = GeometryInfo<dim>::vertices_per_cell;
- Assert (ierr == 0, ExcErrorOpeningTecplotFile(file_name));
+ TecplotMacros tm(n_nodes, vars_per_node, n_cells, nodes_per_cell);
- char FEBLOCK[] = {'F','E','B','L','O','C','K',0};
- ierr = TECZNE (NULL,
- &num_nodes,
- &num_cells,
- &cell_type,
- FEBLOCK,
- NULL);
+ int is_double = 0,
+ tec_debug = 0,
+ cell_type = tecplot_binary_cell_type[dim];
- Assert (ierr == 0, ExcTecplotAPIError());
+ std::string tec_var_names;
+ switch (spacedim)
+ {
+ case 2:
+ tec_var_names = "x y";
+ break;
+ case 3:
+ tec_var_names = "x y z";
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
- int total = (vars_per_node*num_nodes);
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ {
+ tec_var_names += " ";
+ tec_var_names += data_names[data_set];
+ }
+ // in Tecplot FEBLOCK format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
+ Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+ void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+ Table<2,double> &)
+ = &write_gmv_reorder_data_vectors<dim,spacedim>;
+ Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ for (unsigned int d=1; d<=spacedim; ++d)
+ {
+ unsigned int entry=0;
- ierr = TECDAT (&total,
- &tm.nodalData[0],
- &is_double);
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
- Assert (ierr == 0, ExcTecplotAPIError());
+ switch (dim)
+ {
+ case 2:
+ {
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ {
+ const double x_frac = i * 1./n_subdivisions,
+ y_frac = j * 1./n_subdivisions;
- ierr = TECNOD (&tm.connData[0]);
+ tm.nd((d-1),entry) = static_cast<float>(
+ (((patch->vertices[1](d-1) * x_frac) +
+ (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[3](d-1) * x_frac) +
+ (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
+ );
+ entry++;
+ }
+ break;
+ }
- Assert (ierr == 0, ExcTecplotAPIError());
+ case 3:
+ {
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ for (unsigned int k=0; k<n_subdivisions+1; ++k)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ {
+ const double x_frac = i * 1./n_subdivisions,
+ y_frac = k * 1./n_subdivisions,
+ z_frac = j * 1./n_subdivisions;
+
+ // compute coordinates for
+ // this patch point
+ tm.nd((d-1),entry) = static_cast<float>(
+ ((((patch->vertices[1](d-1) * x_frac) +
+ (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[3](d-1) * x_frac) +
+ (patch->vertices[2](d-1) * (1-x_frac))) * y_frac) * (1-z_frac) +
+ (((patch->vertices[5](d-1) * x_frac) +
+ (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[7](d-1) * x_frac) +
+ (patch->vertices[6](d-1) * (1-x_frac))) * y_frac) * z_frac)
+ );
+ entry++;
+ }
+ break;
+ }
- ierr = TECEND ();
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ }
- Assert (ierr == 0, ExcTecplotAPIError());
- }
-#endif
-}
+ ///////////////////////////////////////
+ // data output.
+ //
+ reorder_task.join ();
+ // then write data.
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ for (unsigned int entry=0; entry<data_vectors[data_set].size(); entry++)
+ tm.nd((spacedim+data_set),entry) = static_cast<float>(data_vectors[data_set][entry]);
-template <int dim, int spacedim>
-void
-DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
-#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
-#else
- if (patches.size() == 0)
- return;
-#endif
- VtkStream vtk_out(out, flags);
- const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
- Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- ///////////////////////
- // preamble
- {
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "# vtk DataFile Version 3.0"
- << '\n'
- << "#This file was generated by the deal.II library";
- if (flags.print_date_and_time)
- out << " on "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " at "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec;
- else
- out << ".";
- out << '\n'
- << "ASCII"
- << '\n';
- // now output the data header
- out << "DATASET UNSTRUCTURED_GRID\n"
- << '\n';
- }
+ /////////////////////////////////
+ // now for the cells. note that
+ // vertices are counted from 1 onwards
+ unsigned int first_vertex_of_patch = 0;
+ unsigned int elem=0;
- // if desired, output time and cycle of the simulation, following
- // the instructions at
- // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
- {
- const unsigned int
- n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
- +
- (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
- if (n_metadata > 0)
- out << "FIELD FieldData " << n_metadata << "\n";
-
- if (flags.cycle != std::numeric_limits<unsigned int>::min())
- {
- out << "CYCLE 1 1 int\n"
- << flags.cycle << "\n";
- }
- if (flags.time != std::numeric_limits<double>::min())
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+ patch!=patches.end(); ++patch)
{
- out << "TIME 1 1 double\n"
- << flags.time << "\n";
- }
- }
-
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
- Table<2,double> data_vectors (n_data_sets, n_nodes);
-
- void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
- = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
- Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that we have to print
- // d=1..3 dimensions
- out << "POINTS " << n_nodes << " double" << '\n';
- write_nodes(patches, vtk_out);
- out << '\n';
- /////////////////////////////////
- // now for the cells
- out << "CELLS " << n_cells << ' '
- << n_cells*(GeometryInfo<dim>::vertices_per_cell+1)
- << '\n';
- write_cells(patches, vtk_out);
- out << '\n';
- // next output the types of the
- // cells. since all cells are
- // the same, this is simple
- out << "CELL_TYPES " << n_cells << '\n';
- for (unsigned int i=0; i<n_cells; ++i)
- out << ' ' << vtk_cell_type[dim];
- out << '\n';
- ///////////////////////////////////////
- // data output.
-
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
- reorder_task.join ();
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+ const unsigned int n = n_subdivisions+1;
+ const unsigned int d1=1;
+ const unsigned int d2=n;
+ const unsigned int d3=n*n;
+ // write out the cells making
+ // up this patch
+ switch (dim)
+ {
+ case 2:
+ {
+ for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+1;
+ tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+1;
+ tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
+ tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+1;
- // then write data. the
- // 'POINT_DATA' means: node data
- // (as opposed to cell data, which
- // we do not support explicitly
- // here). all following data sets
- // are point data
- out << "POINT_DATA " << n_nodes
- << '\n';
+ elem++;
+ }
+ break;
+ }
- // when writing, first write out
- // all vector data, then handle the
- // scalar data sets that have been
- // left over
- std::vector<bool> data_set_written (n_data_sets, false);
- for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
- {
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
- ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
- ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- 0, n_data_sets));
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
- - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
- ExcMessage ("Can't declare a vector with more than 3 components "
- "in VTK"));
+ case 3:
+ {
+ for (unsigned int i3=0; i3<n_subdivisions; ++i3)
+ for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ // note: vertex indices start with 1!
- // mark these components as already written:
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
- out << "VECTORS ";
+ tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3 )*d3+1;
+ tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3 )*d3+1;
+ tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3 )*d3+1;
+ tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3 )*d3+1;
+ tm.cd(4,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3+1)*d3+1;
+ tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3+1)*d3+1;
+ tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
+ tm.cd(7,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3+1)*d3+1;
- if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
- else
- {
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
- }
+ elem++;
+ }
+ break;
+ }
- out << " double"
- << '\n';
+ default:
+ Assert (false, ExcNotImplemented());
+ }
- // now write data. pad all
- // vectors to have three
- // components
- for (unsigned int n=0; n<n_nodes; ++n)
- {
- switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
- {
- case 0:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
- << '\n';
- break;
-
- case 1:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
- << '\n';
- break;
- case 2:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
- << '\n';
- break;
-
- default:
- // VTK doesn't
- // support
- // anything else
- // than vectors
- // with 1, 2, or
- // 3 components
- Assert (false, ExcInternalError());
- }
- }
- }
- // now do the left over scalar data sets
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- if (data_set_written[data_set] == false)
- {
- out << "SCALARS "
- << data_names[data_set]
- << " double 1"
- << '\n'
- << "LOOKUP_TABLE default"
- << '\n';
- std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, " "));
- out << '\n';
+ // finally update the number
+ // of the first vertex of this patch
+ first_vertex_of_patch += Utilities::fixed_power<dim>(n);
}
- // make sure everything now gets to
- // disk
- out.flush ();
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+ {
+ int ierr = 0,
+ num_nodes = static_cast<int>(n_nodes),
+ num_cells = static_cast<int>(n_cells);
+ char dot[2] = {'.', 0};
+ // Unfortunately, TECINI takes a
+ // char *, but c_str() gives a
+ // const char *. As we don't do
+ // anything else with
+ // tec_var_names following
+ // const_cast is ok
+ char *var_names=const_cast<char *> (tec_var_names.c_str());
+ ierr = TECINI (NULL,
+ var_names,
+ file_name,
+ dot,
+ &tec_debug,
+ &is_double);
-void DataOutBase::write_vtu_header (std::ostream &out,
- const VtkFlags &flags)
-{
- AssertThrow (out, ExcIO());
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "<?xml version=\"1.0\" ?> \n";
- out << "<!-- \n";
- out << "# vtk DataFile Version 3.0"
- << '\n'
- << "#This file was generated by the deal.II library";
- if (flags.print_date_and_time)
- out << " on "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " at "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec;
- else
- out << ".";
- out << "\n-->\n";
- out << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\"";
-#ifdef DEAL_II_WITH_ZLIB
- out << " compressor=\"vtkZLibDataCompressor\"";
-#endif
-#ifdef DEAL_II_WORDS_BIGENDIAN
- out << " byte_order=\"BigEndian\"";
-#else
- out << " byte_order=\"LittleEndian\"";
-#endif
- out << ">";
- out << '\n';
- out << "<UnstructuredGrid>";
- out << '\n';
-}
+ Assert (ierr == 0, ExcErrorOpeningTecplotFile(file_name));
+ char FEBLOCK[] = {'F','E','B','L','O','C','K',0};
+ ierr = TECZNE (NULL,
+ &num_nodes,
+ &num_cells,
+ &cell_type,
+ FEBLOCK,
+ NULL);
+ Assert (ierr == 0, ExcTecplotAPIError());
-void DataOutBase::write_vtu_footer (std::ostream &out)
-{
- AssertThrow (out, ExcIO());
- out << " </UnstructuredGrid>\n";
- out << "</VTKFile>\n";
-}
+ int total = (vars_per_node*num_nodes);
+ ierr = TECDAT (&total,
+ &tm.nodalData[0],
+ &is_double);
+ Assert (ierr == 0, ExcTecplotAPIError());
-template <int dim, int spacedim>
-void
-DataOutBase::write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out)
-{
- write_vtu_header(out, flags);
- write_vtu_main (patches, data_names, vector_data_ranges, flags, out);
- write_vtu_footer(out);
+ ierr = TECNOD (&tm.connData[0]);
- out << std::flush;
-}
+ Assert (ierr == 0, ExcTecplotAPIError());
+ ierr = TECEND ();
+
+ Assert (ierr == 0, ExcTecplotAPIError());
+ }
+#endif
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+
+
+ template <int dim, int spacedim>
+ void
+ write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
#ifndef DEAL_II_WITH_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
- Assert (patches.size() > 0, ExcNoPatches());
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
#else
- if (patches.size() == 0)
- {
- // we still need to output a valid vtu file, because other CPUs
- // might output data. This is the minimal file that is accepted by paraview and visit.
- // if we remove the field definitions, visit is complaining.
- out << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\" >\n"
- << "<Cells>\n"
- << "<DataArray type=\"UInt8\" Name=\"types\"></DataArray>\n"
- << "</Cells>\n"
- << " <PointData Scalars=\"scalars\">\n";
- std::vector<bool> data_set_written (data_names.size(), false);
- for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
- {
- // mark these components as already
- // written:
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
-
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
- out << " <DataArray type=\"Float64\" Name=\"";
+ if (patches.size() == 0)
+ return;
+#endif
- if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
- else
- {
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
- }
+ VtkStream vtk_out(out, flags);
+
+ const unsigned int n_data_sets = data_names.size();
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
+ Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ ///////////////////////
+ // preamble
+ {
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "# vtk DataFile Version 3.0"
+ << '\n'
+ << "#This file was generated by the deal.II library";
+ if (flags.print_date_and_time)
+ out << " on "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " at "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec;
+ else
+ out << ".";
+ out << '\n'
+ << "ASCII"
+ << '\n';
+ // now output the data header
+ out << "DATASET UNSTRUCTURED_GRID\n"
+ << '\n';
+ }
- out << "\" NumberOfComponents=\"3\"></DataArray>\n";
+ // if desired, output time and cycle of the simulation, following
+ // the instructions at
+ // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
+ {
+ const unsigned int
+ n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
+ +
+ (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
+ if (n_metadata > 0)
+ out << "FIELD FieldData " << n_metadata << "\n";
+
+ if (flags.cycle != std::numeric_limits<unsigned int>::min())
+ {
+ out << "CYCLE 1 1 int\n"
+ << flags.cycle << "\n";
}
+ if (flags.time != std::numeric_limits<double>::min())
+ {
+ out << "TIME 1 1 double\n"
+ << flags.time << "\n";
+ }
+ }
+
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
+ Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+ void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+ Table<2,double> &)
+ = &write_gmv_reorder_data_vectors<dim,spacedim>;
+ Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that we have to print
+ // d=1..3 dimensions
+ out << "POINTS " << n_nodes << " double" << '\n';
+ write_nodes(patches, vtk_out);
+ out << '\n';
+ /////////////////////////////////
+ // now for the cells
+ out << "CELLS " << n_cells << ' '
+ << n_cells*(GeometryInfo<dim>::vertices_per_cell+1)
+ << '\n';
+ write_cells(patches, vtk_out);
+ out << '\n';
+ // next output the types of the
+ // cells. since all cells are
+ // the same, this is simple
+ out << "CELL_TYPES " << n_cells << '\n';
+ for (unsigned int i=0; i<n_cells; ++i)
+ out << ' ' << vtk_cell_type[dim];
+ out << '\n';
+ ///////////////////////////////////////
+ // data output.
+
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
+ reorder_task.join ();
+
+ // then write data. the
+ // 'POINT_DATA' means: node data
+ // (as opposed to cell data, which
+ // we do not support explicitly
+ // here). all following data sets
+ // are point data
+ out << "POINT_DATA " << n_nodes
+ << '\n';
- for (unsigned int data_set=0; data_set<data_names.size(); ++data_set)
- if (data_set_written[data_set] == false)
+ // when writing, first write out
+ // all vector data, then handle the
+ // scalar data sets that have been
+ // left over
+ std::vector<bool> data_set_written (n_data_sets, false);
+ for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
+ {
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+ ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
+ ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ 0, n_data_sets));
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
+ - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+ ExcMessage ("Can't declare a vector with more than 3 components "
+ "in VTK"));
+
+ // mark these components as already written:
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
+ out << "VECTORS ";
+
+ if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ else
{
- out << " <DataArray type=\"Float64\" Name=\""
- << data_names[data_set]
- << "\"></DataArray>\n";
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
}
- out << " </PointData>\n";
- out << "</Piece>\n";
+ out << " double"
+ << '\n';
- out << std::flush;
+ // now write data. pad all
+ // vectors to have three
+ // components
+ for (unsigned int n=0; n<n_nodes; ++n)
+ {
+ switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+ {
+ case 0:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
+ << '\n';
+ break;
- return;
- }
-#endif
+ case 1:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
+ << '\n';
+ break;
+ case 2:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
+ << '\n';
+ break;
- // first up: metadata
- //
- // if desired, output time and cycle of the simulation, following
- // the instructions at
- // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
- {
- const unsigned int
- n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
- +
- (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
- if (n_metadata > 0)
- out << "<FieldData>\n";
-
- if (flags.cycle != std::numeric_limits<unsigned int>::min())
- {
- out << "<DataArray type=\"Float32\" Name=\"CYCLE\" NumberOfTuples=\"1\" format=\"ascii\">"
- << flags.cycle
- << "</DataArray>\n";
- }
- if (flags.time != std::numeric_limits<double>::min())
- {
- out << "<DataArray type=\"Float32\" Name=\"TIME\" NumberOfTuples=\"1\" format=\"ascii\">"
- << flags.time
- << "</DataArray>\n";
+ default:
+ // VTK doesn't
+ // support
+ // anything else
+ // than vectors
+ // with 1, 2, or
+ // 3 components
+ Assert (false, ExcInternalError());
+ }
+ }
}
- if (n_metadata > 0)
- out << "</FieldData>\n";
- }
-
+ // now do the left over scalar data sets
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ if (data_set_written[data_set] == false)
+ {
+ out << "SCALARS "
+ << data_names[data_set]
+ << " double 1"
+ << '\n'
+ << "LOOKUP_TABLE default"
+ << '\n';
+ std::copy (data_vectors[data_set].begin(),
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, " "));
+ out << '\n';
+ }
- VtuStream vtu_out(out, flags);
+ // make sure everything now gets to
+ // disk
+ out.flush ();
- const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
- Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
+ void write_vtu_header (std::ostream &out,
+ const VtkFlags &flags)
+ {
+ AssertThrow (out, ExcIO());
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "<?xml version=\"1.0\" ?> \n";
+ out << "<!-- \n";
+ out << "# vtk DataFile Version 3.0"
+ << '\n'
+ << "#This file was generated by the deal.II library";
+ if (flags.print_date_and_time)
+ out << " on "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " at "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec;
+ else
+ out << ".";
+ out << "\n-->\n";
+ out << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\"";
#ifdef DEAL_II_WITH_ZLIB
- const char *ascii_or_binary = "binary";
+ out << " compressor=\"vtkZLibDataCompressor\"";
+#endif
+#ifdef DEAL_II_WORDS_BIGENDIAN
+ out << " byte_order=\"BigEndian\"";
#else
- const char *ascii_or_binary = "ascii";
+ out << " byte_order=\"LittleEndian\"";
#endif
+ out << ">";
+ out << '\n';
+ out << "<UnstructuredGrid>";
+ out << '\n';
+ }
- // first count the number of cells
- // and cells for later use
- unsigned int n_nodes;
- unsigned int n_cells;
- compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
- Table<2,double> data_vectors (n_data_sets, n_nodes);
-
- void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
- = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
- Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches,
- data_vectors);
-
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that according to the standard, we
- // have to print d=1..3 dimensions, even if
- // we are in reality in 2d, for example
- out << "<Piece NumberOfPoints=\"" << n_nodes
- <<"\" NumberOfCells=\"" << n_cells << "\" >\n";
- out << " <Points>\n";
- out << " <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\""
- << ascii_or_binary << "\">\n";
- write_nodes(patches, vtu_out);
- out << " </DataArray>\n";
- out << " </Points>\n\n";
- /////////////////////////////////
- // now for the cells
- out << " <Cells>\n";
- out << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\""
- << ascii_or_binary << "\">\n";
- write_cells(patches, vtu_out);
- out << " </DataArray>\n";
-
- // XML VTU format uses offsets; this is
- // different than the VTK format, which
- // puts the number of nodes per cell in
- // front of the connectivity list.
- out << " <DataArray type=\"Int32\" Name=\"offsets\" format=\""
- << ascii_or_binary << "\">\n";
-
- std::vector<int32_t> offsets (n_cells);
- for (unsigned int i=0; i<n_cells; ++i)
- offsets[i] = (i+1)*GeometryInfo<dim>::vertices_per_cell;
- vtu_out << offsets;
- out << "\n";
- out << " </DataArray>\n";
-
- // next output the types of the
- // cells. since all cells are
- // the same, this is simple
- out << " <DataArray type=\"UInt8\" Name=\"types\" format=\""
- << ascii_or_binary << "\">\n";
+ void write_vtu_footer (std::ostream &out)
{
- // uint8_t might be a typedef to unsigned
- // char which is then not printed as
- // ascii integers
-#ifdef DEAL_II_WITH_ZLIB
- std::vector<uint8_t> cell_types (n_cells,
- static_cast<uint8_t>(vtk_cell_type[dim]));
-#else
- std::vector<unsigned int> cell_types (n_cells,
- vtk_cell_type[dim]);
-#endif
- // this should compress well :-)
- vtu_out << cell_types;
+ AssertThrow (out, ExcIO());
+ out << " </UnstructuredGrid>\n";
+ out << "</VTKFile>\n";
}
- out << "\n";
- out << " </DataArray>\n";
- out << " </Cells>\n";
- ///////////////////////////////////////
- // data output.
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
- reorder_task.join ();
+ template <int dim, int spacedim>
+ void
+ write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out)
+ {
+ write_vtu_header(out, flags);
+ write_vtu_main (patches, data_names, vector_data_ranges, flags, out);
+ write_vtu_footer(out);
- // then write data. the
- // 'POINT_DATA' means: node data
- // (as opposed to cell data, which
- // we do not support explicitly
- // here). all following data sets
- // are point data
- out << " <PointData Scalars=\"scalars\">\n";
+ out << std::flush;
+ }
- // when writing, first write out
- // all vector data, then handle the
- // scalar data sets that have been
- // left over
- std::vector<bool> data_set_written (n_data_sets, false);
- for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
- {
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
- ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
- ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- 0, n_data_sets));
- AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
- - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
- ExcMessage ("Can't declare a vector with more than 3 components "
- "in VTK"));
- // mark these components as already
- // written:
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
+ template <int dim, int spacedim>
+ void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
- out << " <DataArray type=\"Float64\" Name=\"";
+#ifndef DEAL_II_WITH_MPI
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
+ Assert (patches.size() > 0, ExcNoPatches());
+#else
+ if (patches.size() == 0)
+ {
+ // we still need to output a valid vtu file, because other CPUs
+ // might output data. This is the minimal file that is accepted by paraview and visit.
+ // if we remove the field definitions, visit is complaining.
+ out << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\" >\n"
+ << "<Cells>\n"
+ << "<DataArray type=\"UInt8\" Name=\"types\"></DataArray>\n"
+ << "</Cells>\n"
+ << " <PointData Scalars=\"scalars\">\n";
+ std::vector<bool> data_set_written (data_names.size(), false);
+ for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
+ {
+ // mark these components as already
+ // written:
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
+ out << " <DataArray type=\"Float64\" Name=\"";
+
+ if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ else
+ {
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ }
- if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
- else
+ out << "\" NumberOfComponents=\"3\"></DataArray>\n";
+ }
+
+ for (unsigned int data_set=0; data_set<data_names.size(); ++data_set)
+ if (data_set_written[data_set] == false)
+ {
+ out << " <DataArray type=\"Float64\" Name=\""
+ << data_names[data_set]
+ << "\"></DataArray>\n";
+ }
+
+ out << " </PointData>\n";
+ out << "</Piece>\n";
+
+ out << std::flush;
+
+ return;
+ }
+#endif
+
+ // first up: metadata
+ //
+ // if desired, output time and cycle of the simulation, following
+ // the instructions at
+ // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
+ {
+ const unsigned int
+ n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
+ +
+ (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
+ if (n_metadata > 0)
+ out << "<FieldData>\n";
+
+ if (flags.cycle != std::numeric_limits<unsigned int>::min())
{
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ out << "<DataArray type=\"Float32\" Name=\"CYCLE\" NumberOfTuples=\"1\" format=\"ascii\">"
+ << flags.cycle
+ << "</DataArray>\n";
}
+ if (flags.time != std::numeric_limits<double>::min())
+ {
+ out << "<DataArray type=\"Float32\" Name=\"TIME\" NumberOfTuples=\"1\" format=\"ascii\">"
+ << flags.time
+ << "</DataArray>\n";
+ }
+
+ if (n_metadata > 0)
+ out << "</FieldData>\n";
+ }
+
+
+ VtuStream vtu_out(out, flags);
+
+ const unsigned int n_data_sets = data_names.size();
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
+ Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+
+#ifdef DEAL_II_WITH_ZLIB
+ const char *ascii_or_binary = "binary";
+#else
+ const char *ascii_or_binary = "ascii";
+#endif
- out << "\" NumberOfComponents=\"3\" format=\""
- << ascii_or_binary << "\">\n";
- // now write data. pad all
- // vectors to have three
- // components
- std::vector<double> data;
- data.reserve (n_nodes*dim);
+ // first count the number of cells
+ // and cells for later use
+ unsigned int n_nodes;
+ unsigned int n_cells;
+ compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
+ Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+ void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+ Table<2,double> &)
+ = &write_gmv_reorder_data_vectors<dim,spacedim>;
+ Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches,
+ data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that according to the standard, we
+ // have to print d=1..3 dimensions, even if
+ // we are in reality in 2d, for example
+ out << "<Piece NumberOfPoints=\"" << n_nodes
+ <<"\" NumberOfCells=\"" << n_cells << "\" >\n";
+ out << " <Points>\n";
+ out << " <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\""
+ << ascii_or_binary << "\">\n";
+ write_nodes(patches, vtu_out);
+ out << " </DataArray>\n";
+ out << " </Points>\n\n";
+ /////////////////////////////////
+ // now for the cells
+ out << " <Cells>\n";
+ out << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\""
+ << ascii_or_binary << "\">\n";
+ write_cells(patches, vtu_out);
+ out << " </DataArray>\n";
+
+ // XML VTU format uses offsets; this is
+ // different than the VTK format, which
+ // puts the number of nodes per cell in
+ // front of the connectivity list.
+ out << " <DataArray type=\"Int32\" Name=\"offsets\" format=\""
+ << ascii_or_binary << "\">\n";
+
+ std::vector<int32_t> offsets (n_cells);
+ for (unsigned int i=0; i<n_cells; ++i)
+ offsets[i] = (i+1)*GeometryInfo<dim>::vertices_per_cell;
+ vtu_out << offsets;
+ out << "\n";
+ out << " </DataArray>\n";
+
+ // next output the types of the
+ // cells. since all cells are
+ // the same, this is simple
+ out << " <DataArray type=\"UInt8\" Name=\"types\" format=\""
+ << ascii_or_binary << "\">\n";
- for (unsigned int n=0; n<n_nodes; ++n)
- {
- switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
- {
- case 0:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (0);
- data.push_back (0);
- break;
-
- case 1:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
- data.push_back (0);
- break;
- case 2:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
- break;
-
- default:
- // VTK doesn't
- // support
- // anything else
- // than vectors
- // with 1, 2, or
- // 3 components
- Assert (false, ExcInternalError());
- }
- }
- vtu_out << data;
- out << " </DataArray>\n";
+ {
+ // uint8_t might be a typedef to unsigned
+ // char which is then not printed as
+ // ascii integers
+#ifdef DEAL_II_WITH_ZLIB
+ std::vector<uint8_t> cell_types (n_cells,
+ static_cast<uint8_t>(vtk_cell_type[dim]));
+#else
+ std::vector<unsigned int> cell_types (n_cells,
+ vtk_cell_type[dim]);
+#endif
+ // this should compress well :-)
+ vtu_out << cell_types;
}
-
- // now do the left over scalar data sets
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- if (data_set_written[data_set] == false)
+ out << "\n";
+ out << " </DataArray>\n";
+ out << " </Cells>\n";
+
+
+ ///////////////////////////////////////
+ // data output.
+
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
+ reorder_task.join ();
+
+ // then write data. the
+ // 'POINT_DATA' means: node data
+ // (as opposed to cell data, which
+ // we do not support explicitly
+ // here). all following data sets
+ // are point data
+ out << " <PointData Scalars=\"scalars\">\n";
+
+ // when writing, first write out
+ // all vector data, then handle the
+ // scalar data sets that have been
+ // left over
+ std::vector<bool> data_set_written (n_data_sets, false);
+ for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
{
- out << " <DataArray type=\"Float64\" Name=\""
- << data_names[data_set]
- << "\" format=\""
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+ ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
+ ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ 0, n_data_sets));
+ AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
+ - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+ ExcMessage ("Can't declare a vector with more than 3 components "
+ "in VTK"));
+
+ // mark these components as already
+ // written:
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
+ out << " <DataArray type=\"Float64\" Name=\"";
+
+ if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ else
+ {
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ }
+
+ out << "\" NumberOfComponents=\"3\" format=\""
<< ascii_or_binary << "\">\n";
- std::vector<double> data (data_vectors[data_set].begin(),
- data_vectors[data_set].end());
+ // now write data. pad all
+ // vectors to have three
+ // components
+ std::vector<double> data;
+ data.reserve (n_nodes*dim);
+
+ for (unsigned int n=0; n<n_nodes; ++n)
+ {
+ switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+ {
+ case 0:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (0);
+ data.push_back (0);
+ break;
+
+ case 1:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+ data.push_back (0);
+ break;
+ case 2:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
+ break;
+
+ default:
+ // VTK doesn't
+ // support
+ // anything else
+ // than vectors
+ // with 1, 2, or
+ // 3 components
+ Assert (false, ExcInternalError());
+ }
+ }
vtu_out << data;
out << " </DataArray>\n";
}
- out << " </PointData>\n";
+ // now do the left over scalar data sets
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ if (data_set_written[data_set] == false)
+ {
+ out << " <DataArray type=\"Float64\" Name=\""
+ << data_names[data_set]
+ << "\" format=\""
+ << ascii_or_binary << "\">\n";
+
+ std::vector<double> data (data_vectors[data_set].begin(),
+ data_vectors[data_set].end());
+ vtu_out << data;
+ out << " </DataArray>\n";
+ }
+
+ out << " </PointData>\n";
- // Finish up writing a valid XML file
- out << " </Piece>\n";
+ // Finish up writing a valid XML file
+ out << " </Piece>\n";
- // make sure everything now gets to
- // disk
- out.flush ();
+ // make sure everything now gets to
+ // disk
+ out.flush ();
- // assert the stream is still ok
- AssertThrow (out, ExcIO());
-}
+ // assert the stream is still ok
+ AssertThrow (out, ExcIO());
+ }
-template <>
-void DataOutBase::write_svg<1,1> (const std::vector<Patch<1,1> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const SvgFlags &flags,
- std::ostream &out)
-{
- AssertThrow (false, ExcNotImplemented());
-}
+ template <int dim, int spacedim>
+ void write_svg (const std::vector<Patch<dim,spacedim> > &,
+ const std::vector<std::string> &,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const SvgFlags &,
+ std::ostream &)
+ {
+ Assert (false, ExcNotImplemented());
+ }
-template <int dim, int spacedim>
-void DataOutBase::write_svg (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const SvgFlags &flags,
- std::ostream &out)
-{
- // do not allow volume rendering
- AssertThrow (dim==2, ExcNotImplemented());
+ template <int spacedim>
+ void write_svg (const std::vector<Patch<2,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const SvgFlags &flags,
+ std::ostream &out)
+ {
+ const int dim = 2;
+ const unsigned int height = flags.height;
+ unsigned int width = flags.width;
+
+ // margin around the plotted area
+ unsigned int margin_in_percent = 0;
+ if (flags.margin) margin_in_percent = 5;
- const unsigned int height = flags.height;
- unsigned int width = flags.width;
- // margin around the plotted area
- unsigned int margin_in_percent = 0;
- if (flags.margin) margin_in_percent = 5;
+ // determine the bounding box in the model space
+ double x_dimension, y_dimension, z_dimension;
+ typename std::vector<Patch<dim,spacedim> >::const_iterator patch = patches.begin();
- // determine the bounding box in the model space
- double x_dimension, y_dimension, z_dimension;
+ unsigned int n_subdivisions = patch->n_subdivisions;
+ unsigned int n = n_subdivisions + 1;
+ const unsigned int d1 = 1;
+ const unsigned int d2 = n;
- typename std::vector<Patch<dim,spacedim> >::const_iterator patch = patches.begin();
+ Point<spacedim> projected_point;
+ Point<spacedim> projected_points[4];
- unsigned int n_subdivisions = patch->n_subdivisions;
- unsigned int n = n_subdivisions + 1;
- const unsigned int d1 = 1;
- const unsigned int d2 = n;
+ Point<2> projection_decomposition;
+ Point<2> projection_decompositions[4];
- Point<spacedim> projected_point;
- Point<spacedim> projected_points[4];
+ compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
- Point<2> projection_decomposition;
- Point<2> projection_decompositions[4];
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
- compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
+ double x_min = projected_point[0];
+ double x_max = x_min;
+ double y_min = projected_point[1];
+ double y_max = y_min;
+ double z_min = patch->data.n_rows() != 0 ? patch->data(flags.height_vector,0) : 0;
+ double z_max = z_min;
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+ // iterate over the patches
+ for (; patch != patches.end(); ++patch)
+ {
+ n_subdivisions = patch->n_subdivisions;
+ n = n_subdivisions + 1;
- double x_min = projected_point[0];
- double x_max = x_min;
- double y_min = projected_point[1];
- double y_max = y_min;
- double z_min = patch->data.n_rows() != 0 ? patch->data(flags.height_vector,0) : 0;
- double z_max = z_min;
+ for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+ {
+ for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+ {
+ compute_node(projected_points[0], &*patch, i1, i2, 0, n_subdivisions);
+ compute_node(projected_points[1], &*patch, i1+1, i2, 0, n_subdivisions);
+ compute_node(projected_points[2], &*patch, i1, i2+1, 0, n_subdivisions);
+ compute_node(projected_points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
+
+ x_min = std::min(x_min, (double)projected_points[0][0]);
+ x_min = std::min(x_min, (double)projected_points[1][0]);
+ x_min = std::min(x_min, (double)projected_points[2][0]);
+ x_min = std::min(x_min, (double)projected_points[3][0]);
+
+ x_max = std::max(x_max, (double)projected_points[0][0]);
+ x_max = std::max(x_max, (double)projected_points[1][0]);
+ x_max = std::max(x_max, (double)projected_points[2][0]);
+ x_max = std::max(x_max, (double)projected_points[3][0]);
+
+ y_min = std::min(y_min, (double)projected_points[0][1]);
+ y_min = std::min(y_min, (double)projected_points[1][1]);
+ y_min = std::min(y_min, (double)projected_points[2][1]);
+ y_min = std::min(y_min, (double)projected_points[3][1]);
+
+ y_max = std::max(y_max, (double)projected_points[0][1]);
+ y_max = std::max(y_max, (double)projected_points[1][1]);
+ y_max = std::max(y_max, (double)projected_points[2][1]);
+ y_max = std::max(y_max, (double)projected_points[3][1]);
- // iterate over the patches
- for (; patch != patches.end(); ++patch)
- {
- n_subdivisions = patch->n_subdivisions;
- n = n_subdivisions + 1;
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
- for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
- {
- for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
- {
- compute_node(projected_points[0], &*patch, i1, i2, 0, n_subdivisions);
- compute_node(projected_points[1], &*patch, i1+1, i2, 0, n_subdivisions);
- compute_node(projected_points[2], &*patch, i1, i2+1, 0, n_subdivisions);
- compute_node(projected_points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
- x_min = std::min(x_min, (double)projected_points[0][0]);
- x_min = std::min(x_min, (double)projected_points[1][0]);
- x_min = std::min(x_min, (double)projected_points[2][0]);
- x_min = std::min(x_min, (double)projected_points[3][0]);
-
- x_max = std::max(x_max, (double)projected_points[0][0]);
- x_max = std::max(x_max, (double)projected_points[1][0]);
- x_max = std::max(x_max, (double)projected_points[2][0]);
- x_max = std::max(x_max, (double)projected_points[3][0]);
-
- y_min = std::min(y_min, (double)projected_points[0][1]);
- y_min = std::min(y_min, (double)projected_points[1][1]);
- y_min = std::min(y_min, (double)projected_points[2][1]);
- y_min = std::min(y_min, (double)projected_points[3][1]);
-
- y_max = std::max(y_max, (double)projected_points[0][1]);
- y_max = std::max(y_max, (double)projected_points[1][1]);
- y_max = std::max(y_max, (double)projected_points[2][1]);
- y_max = std::max(y_max, (double)projected_points[3][1]);
-
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
-
- z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
- z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
- z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
- z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
-
- z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
- z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
- z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
- z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
- }
- }
- }
+ z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
+ z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
+ z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
+ z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
+
+ z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
+ z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
+ z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
+ z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
+ }
+ }
+ }
- x_dimension = x_max - x_min;
- y_dimension = y_max - y_min;
- z_dimension = z_max - z_min;
+ x_dimension = x_max - x_min;
+ y_dimension = y_max - y_min;
+ z_dimension = z_max - z_min;
// set initial camera position
- Point<3> camera_position(true);
- Point<3> camera_direction(true);
- Point<3> camera_horizontal(true);
- float camera_focus = 0;
+ Point<3> camera_position(true);
+ Point<3> camera_direction(true);
+ Point<3> camera_horizontal(true);
+ float camera_focus = 0;
- // translate camera from the origin to the initial position
- camera_position[0] = 0.;
- camera_position[1] = 0.;
- camera_position[2] = z_min + 2. * z_dimension;
+ // translate camera from the origin to the initial position
+ camera_position[0] = 0.;
+ camera_position[1] = 0.;
+ camera_position[2] = z_min + 2. * z_dimension;
- camera_direction[0] = 0.;
- camera_direction[1] = 0.;
- camera_direction[2] = - 1.;
+ camera_direction[0] = 0.;
+ camera_direction[1] = 0.;
+ camera_direction[2] = - 1.;
- camera_horizontal[0] = 1.;
- camera_horizontal[1] = 0.;
- camera_horizontal[2] = 0.;
+ camera_horizontal[0] = 1.;
+ camera_horizontal[1] = 0.;
+ camera_horizontal[2] = 0.;
- camera_focus = .5 * z_dimension;
+ camera_focus = .5 * z_dimension;
- Point<3> camera_position_temp;
- Point<3> camera_direction_temp;
- Point<3> camera_horizontal_temp;
+ Point<3> camera_position_temp;
+ Point<3> camera_direction_temp;
+ Point<3> camera_horizontal_temp;
- const float angle_factor = 3.14159265 / 180.;
+ const float angle_factor = 3.14159265 / 180.;
- // (I) rotate the camera to the chosen polar angle
- camera_position_temp[1] = cos(angle_factor * flags.polar_angle) * camera_position[1] - sin(angle_factor * flags.polar_angle) * camera_position[2];
- camera_position_temp[2] = sin(angle_factor * flags.polar_angle) * camera_position[1] + cos(angle_factor * flags.polar_angle) * camera_position[2];
+ // (I) rotate the camera to the chosen polar angle
+ camera_position_temp[1] = cos(angle_factor * flags.polar_angle) * camera_position[1] - sin(angle_factor * flags.polar_angle) * camera_position[2];
+ camera_position_temp[2] = sin(angle_factor * flags.polar_angle) * camera_position[1] + cos(angle_factor * flags.polar_angle) * camera_position[2];
- camera_direction_temp[1] = cos(angle_factor * flags.polar_angle) * camera_direction[1] - sin(angle_factor * flags.polar_angle) * camera_direction[2];
- camera_direction_temp[2] = sin(angle_factor * flags.polar_angle) * camera_direction[1] + cos(angle_factor * flags.polar_angle) * camera_direction[2];
+ camera_direction_temp[1] = cos(angle_factor * flags.polar_angle) * camera_direction[1] - sin(angle_factor * flags.polar_angle) * camera_direction[2];
+ camera_direction_temp[2] = sin(angle_factor * flags.polar_angle) * camera_direction[1] + cos(angle_factor * flags.polar_angle) * camera_direction[2];
- camera_horizontal_temp[1] = cos(angle_factor * flags.polar_angle) * camera_horizontal[1] - sin(angle_factor * flags.polar_angle) * camera_horizontal[2];
- camera_horizontal_temp[2] = sin(angle_factor * flags.polar_angle) * camera_horizontal[1] + cos(angle_factor * flags.polar_angle) * camera_horizontal[2];
+ camera_horizontal_temp[1] = cos(angle_factor * flags.polar_angle) * camera_horizontal[1] - sin(angle_factor * flags.polar_angle) * camera_horizontal[2];
+ camera_horizontal_temp[2] = sin(angle_factor * flags.polar_angle) * camera_horizontal[1] + cos(angle_factor * flags.polar_angle) * camera_horizontal[2];
- camera_position[1] = camera_position_temp[1];
- camera_position[2] = camera_position_temp[2];
+ camera_position[1] = camera_position_temp[1];
+ camera_position[2] = camera_position_temp[2];
- camera_direction[1] = camera_direction_temp[1];
- camera_direction[2] = camera_direction_temp[2];
+ camera_direction[1] = camera_direction_temp[1];
+ camera_direction[2] = camera_direction_temp[2];
- camera_horizontal[1] = camera_horizontal_temp[1];
- camera_horizontal[2] = camera_horizontal_temp[2];
+ camera_horizontal[1] = camera_horizontal_temp[1];
+ camera_horizontal[2] = camera_horizontal_temp[2];
- // (II) rotate the camera to the chosen azimuth angle
- camera_position_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_position[0] - sin(angle_factor * flags.azimuth_angle) * camera_position[1];
- camera_position_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_position[0] + cos(angle_factor * flags.azimuth_angle) * camera_position[1];
+ // (II) rotate the camera to the chosen azimuth angle
+ camera_position_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_position[0] - sin(angle_factor * flags.azimuth_angle) * camera_position[1];
+ camera_position_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_position[0] + cos(angle_factor * flags.azimuth_angle) * camera_position[1];
- camera_direction_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_direction[0] - sin(angle_factor * flags.azimuth_angle) * camera_direction[1];
- camera_direction_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_direction[0] + cos(angle_factor * flags.azimuth_angle) * camera_direction[1];
+ camera_direction_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_direction[0] - sin(angle_factor * flags.azimuth_angle) * camera_direction[1];
+ camera_direction_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_direction[0] + cos(angle_factor * flags.azimuth_angle) * camera_direction[1];
- camera_horizontal_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_horizontal[0] - sin(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
- camera_horizontal_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_horizontal[0] + cos(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
+ camera_horizontal_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_horizontal[0] - sin(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
+ camera_horizontal_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_horizontal[0] + cos(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
- camera_position[0] = camera_position_temp[0];
- camera_position[1] = camera_position_temp[1];
+ camera_position[0] = camera_position_temp[0];
+ camera_position[1] = camera_position_temp[1];
- camera_direction[0] = camera_direction_temp[0];
- camera_direction[1] = camera_direction_temp[1];
+ camera_direction[0] = camera_direction_temp[0];
+ camera_direction[1] = camera_direction_temp[1];
- camera_horizontal[0] = camera_horizontal_temp[0];
- camera_horizontal[1] = camera_horizontal_temp[1];
+ camera_horizontal[0] = camera_horizontal_temp[0];
+ camera_horizontal[1] = camera_horizontal_temp[1];
- // (III) translate the camera
- camera_position[0] = x_min + .5 * x_dimension;
- camera_position[1] = y_min + .5 * y_dimension;
+ // (III) translate the camera
+ camera_position[0] = x_min + .5 * x_dimension;
+ camera_position[1] = y_min + .5 * y_dimension;
- camera_position[0] += (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * sin(angle_factor * flags.azimuth_angle);
- camera_position[1] -= (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * cos(angle_factor * flags.azimuth_angle);
+ camera_position[0] += (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * sin(angle_factor * flags.azimuth_angle);
+ camera_position[1] -= (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * cos(angle_factor * flags.azimuth_angle);
// determine the bounding box on the projection plane
- double x_min_perspective, y_min_perspective;
- double x_max_perspective, y_max_perspective;
- double x_dimension_perspective, y_dimension_perspective;
-
- patch = patches.begin();
+ double x_min_perspective, y_min_perspective;
+ double x_max_perspective, y_max_perspective;
+ double x_dimension_perspective, y_dimension_perspective;
- n_subdivisions = patch->n_subdivisions;
- n = n_subdivisions + 1;
+ patch = patches.begin();
- Point<3> point(true);
+ n_subdivisions = patch->n_subdivisions;
+ n = n_subdivisions + 1;
- compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
+ Point<3> point(true);
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+ compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
- point[0] = projected_point[0];
- point[1] = projected_point[1];
- point[2] = patch->data.n_rows() != 0 ? patch->data(flags.height_vector, 0) : 0;
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
- projection_decomposition = svg_project_point(point, camera_position, camera_direction, camera_horizontal, camera_focus);
+ point[0] = projected_point[0];
+ point[1] = projected_point[1];
+ point[2] = patch->data.n_rows() != 0 ? patch->data(flags.height_vector, 0) : 0;
- x_min_perspective = projection_decomposition[0];
- x_max_perspective = projection_decomposition[0];
- y_min_perspective = projection_decomposition[1];
- y_max_perspective = projection_decomposition[1];
+ projection_decomposition = svg_project_point(point, camera_position, camera_direction, camera_horizontal, camera_focus);
- // iterate over the patches
- for (; patch != patches.end(); ++patch)
- {
- n_subdivisions = patch->n_subdivisions;
- n = n_subdivisions + 1;
+ x_min_perspective = projection_decomposition[0];
+ x_max_perspective = projection_decomposition[0];
+ y_min_perspective = projection_decomposition[1];
+ y_max_perspective = projection_decomposition[1];
- for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
- {
- for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
- {
- Point<spacedim> projected_vertices[4];
- Point<3> vertices[4];
-
- compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
- compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
- compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
- compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
-
- vertices[0][0] = projected_vertices[0][0];
- vertices[0][1] = projected_vertices[0][1];
- vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
-
- vertices[1][0] = projected_vertices[1][0];
- vertices[1][1] = projected_vertices[1][1];
- vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
-
- vertices[2][0] = projected_vertices[2][0];
- vertices[2][1] = projected_vertices[2][1];
- vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
-
- vertices[3][0] = projected_vertices[3][0];
- vertices[3][1] = projected_vertices[3][1];
- vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
-
- projection_decompositions[0] = svg_project_point(vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
- projection_decompositions[1] = svg_project_point(vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
- projection_decompositions[2] = svg_project_point(vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
- projection_decompositions[3] = svg_project_point(vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
-
- x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[0][0]);
- x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[1][0]);
- x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[2][0]);
- x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[3][0]);
-
- x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[0][0]);
- x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[1][0]);
- x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[2][0]);
- x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[3][0]);
-
- y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[0][1]);
- y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[1][1]);
- y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[2][1]);
- y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[3][1]);
-
- y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[0][1]);
- y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[1][1]);
- y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[2][1]);
- y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[3][1]);
- }
- }
- }
+ // iterate over the patches
+ for (; patch != patches.end(); ++patch)
+ {
+ n_subdivisions = patch->n_subdivisions;
+ n = n_subdivisions + 1;
- x_dimension_perspective = x_max_perspective - x_min_perspective;
- y_dimension_perspective = y_max_perspective - y_min_perspective;
+ for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+ {
+ for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+ {
+ Point<spacedim> projected_vertices[4];
+ Point<3> vertices[4];
- std::multiset<SvgCell> cells;
+ compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
+ compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
+ compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
+ compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
- // iterate over the patches
- for (patch = patches.begin(); patch != patches.end(); ++patch)
- {
- n_subdivisions = patch->n_subdivisions;
- n = n_subdivisions + 1;
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+
+ vertices[0][0] = projected_vertices[0][0];
+ vertices[0][1] = projected_vertices[0][1];
+ vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
+
+ vertices[1][0] = projected_vertices[1][0];
+ vertices[1][1] = projected_vertices[1][1];
+ vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
+
+ vertices[2][0] = projected_vertices[2][0];
+ vertices[2][1] = projected_vertices[2][1];
+ vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
+
+ vertices[3][0] = projected_vertices[3][0];
+ vertices[3][1] = projected_vertices[3][1];
+ vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
+
+ projection_decompositions[0] = svg_project_point(vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
+ projection_decompositions[1] = svg_project_point(vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
+ projection_decompositions[2] = svg_project_point(vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
+ projection_decompositions[3] = svg_project_point(vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
+
+ x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[0][0]);
+ x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[1][0]);
+ x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[2][0]);
+ x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[3][0]);
+
+ x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[0][0]);
+ x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[1][0]);
+ x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[2][0]);
+ x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[3][0]);
+
+ y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[0][1]);
+ y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[1][1]);
+ y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[2][1]);
+ y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[3][1]);
+
+ y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[0][1]);
+ y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[1][1]);
+ y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[2][1]);
+ y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[3][1]);
+ }
+ }
+ }
- for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
- {
- for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
- {
- Point<spacedim> projected_vertices[4];
- SvgCell cell;
+ x_dimension_perspective = x_max_perspective - x_min_perspective;
+ y_dimension_perspective = y_max_perspective - y_min_perspective;
- compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
- compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
- compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
- compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
+ std::multiset<SvgCell> cells;
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+ // iterate over the patches
+ for (patch = patches.begin(); patch != patches.end(); ++patch)
+ {
+ n_subdivisions = patch->n_subdivisions;
+ n = n_subdivisions + 1;
- cell.vertices[0][0] = projected_vertices[0][0];
- cell.vertices[0][1] = projected_vertices[0][1];
- cell.vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
+ for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+ {
+ for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+ {
+ Point<spacedim> projected_vertices[4];
+ SvgCell cell;
- cell.vertices[1][0] = projected_vertices[1][0];
- cell.vertices[1][1] = projected_vertices[1][1];
- cell.vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
+ compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
+ compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
+ compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
+ compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
- cell.vertices[2][0] = projected_vertices[2][0];
- cell.vertices[2][1] = projected_vertices[2][1];
- cell.vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
- cell.vertices[3][0] = projected_vertices[3][0];
- cell.vertices[3][1] = projected_vertices[3][1];
- cell.vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
+ cell.vertices[0][0] = projected_vertices[0][0];
+ cell.vertices[0][1] = projected_vertices[0][1];
+ cell.vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
- cell.projected_vertices[0] = svg_project_point(cell.vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
- cell.projected_vertices[1] = svg_project_point(cell.vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
- cell.projected_vertices[2] = svg_project_point(cell.vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
- cell.projected_vertices[3] = svg_project_point(cell.vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.vertices[1][0] = projected_vertices[1][0];
+ cell.vertices[1][1] = projected_vertices[1][1];
+ cell.vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
- cell.center = .25 * (cell.vertices[0] + cell.vertices[1] + cell.vertices[2] + cell.vertices[3]);
- cell.projected_center = svg_project_point(cell.center, camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.vertices[2][0] = projected_vertices[2][0];
+ cell.vertices[2][1] = projected_vertices[2][1];
+ cell.vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
- cell.depth = cell.center.distance(camera_position);
+ cell.vertices[3][0] = projected_vertices[3][0];
+ cell.vertices[3][1] = projected_vertices[3][1];
+ cell.vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
- cells.insert(cell);
- }
- }
- }
+ cell.projected_vertices[0] = svg_project_point(cell.vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.projected_vertices[1] = svg_project_point(cell.vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.projected_vertices[2] = svg_project_point(cell.vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.projected_vertices[3] = svg_project_point(cell.vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
+ cell.center = .25 * (cell.vertices[0] + cell.vertices[1] + cell.vertices[2] + cell.vertices[3]);
+ cell.projected_center = svg_project_point(cell.center, camera_position, camera_direction, camera_horizontal, camera_focus);
-// write the svg file
- if (width==0)
- width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
- unsigned int additional_width = 0;
+ cell.depth = cell.center.distance(camera_position);
- if (flags.draw_colorbar) additional_width = static_cast<unsigned int>(.5 + height * .3); // additional width for colorbar
+ cells.insert(cell);
+ }
+ }
+ }
- // basic svg header and background rectangle
- out << "<svg width=\"" << width + additional_width << "\" height=\"" << height << "\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">" << '\n'
- << " <rect width=\"" << width + additional_width << "\" height=\"" << height << "\" style=\"fill:white\"/>" << '\n' << '\n';
- unsigned int triangle_counter = 0;
+ // write the svg file
+ if (width==0)
+ width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
+ unsigned int additional_width = 0;
- // write the cells in the correct order
- for (typename std::multiset<SvgCell>::const_iterator cell = cells.begin(); cell != cells.end(); ++cell)
- {
- Point<3> points3d_triangle[3];
+ if (flags.draw_colorbar) additional_width = static_cast<unsigned int>(.5 + height * .3); // additional width for colorbar
- for (unsigned int triangle_index = 0; triangle_index < 4; triangle_index++)
- {
- switch (triangle_index)
- {
- case 0:
- points3d_triangle[0] = cell->vertices[0], points3d_triangle[1] = cell->vertices[1], points3d_triangle[2] = cell->center;
- break;
- case 1:
- points3d_triangle[0] = cell->vertices[1], points3d_triangle[1] = cell->vertices[3], points3d_triangle[2] = cell->center;
- break;
- case 2:
- points3d_triangle[0] = cell->vertices[3], points3d_triangle[1] = cell->vertices[2], points3d_triangle[2] = cell->center;
- break;
- case 3:
- points3d_triangle[0] = cell->vertices[2], points3d_triangle[1] = cell->vertices[0], points3d_triangle[2] = cell->center;
- break;
- default:
- break;
- }
+ // basic svg header and background rectangle
+ out << "<svg width=\"" << width + additional_width << "\" height=\"" << height << "\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">" << '\n'
+ << " <rect width=\"" << width + additional_width << "\" height=\"" << height << "\" style=\"fill:white\"/>" << '\n' << '\n';
- Point<6> gradient_param = svg_get_gradient_parameters(points3d_triangle);
+ unsigned int triangle_counter = 0;
- double start_h = .667 - ((gradient_param[4] - z_min) / z_dimension) * .667;
- double stop_h = .667 - ((gradient_param[5] - z_min) / z_dimension) * .667;
+ // write the cells in the correct order
+ for (typename std::multiset<SvgCell>::const_iterator cell = cells.begin(); cell != cells.end(); ++cell)
+ {
+ Point<3> points3d_triangle[3];
- unsigned int start_r = 0;
- unsigned int start_g = 0;
- unsigned int start_b = 0;
+ for (unsigned int triangle_index = 0; triangle_index < 4; triangle_index++)
+ {
+ switch (triangle_index)
+ {
+ case 0:
+ points3d_triangle[0] = cell->vertices[0], points3d_triangle[1] = cell->vertices[1], points3d_triangle[2] = cell->center;
+ break;
+ case 1:
+ points3d_triangle[0] = cell->vertices[1], points3d_triangle[1] = cell->vertices[3], points3d_triangle[2] = cell->center;
+ break;
+ case 2:
+ points3d_triangle[0] = cell->vertices[3], points3d_triangle[1] = cell->vertices[2], points3d_triangle[2] = cell->center;
+ break;
+ case 3:
+ points3d_triangle[0] = cell->vertices[2], points3d_triangle[1] = cell->vertices[0], points3d_triangle[2] = cell->center;
+ break;
+ default:
+ break;
+ }
- unsigned int stop_r = 0;
- unsigned int stop_g = 0;
- unsigned int stop_b = 0;
+ Point<6> gradient_param = svg_get_gradient_parameters(points3d_triangle);
- unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
- unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
+ double start_h = .667 - ((gradient_param[4] - z_min) / z_dimension) * .667;
+ double stop_h = .667 - ((gradient_param[5] - z_min) / z_dimension) * .667;
- double start_f = start_h * 6. - start_i;
- double start_q = 1. - start_f;
+ unsigned int start_r = 0;
+ unsigned int start_g = 0;
+ unsigned int start_b = 0;
- double stop_f = stop_h * 6. - stop_i;
- double stop_q = 1. - stop_f;
+ unsigned int stop_r = 0;
+ unsigned int stop_g = 0;
+ unsigned int stop_b = 0;
- switch (start_i % 6)
- {
- case 0:
- start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
- break;
- case 1:
- start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
- break;
- case 2:
- start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
- break;
- case 3:
- start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
- break;
- case 4:
- start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
- break;
- case 5:
- start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
- break;
- default:
- break;
- }
+ unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
+ unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
- switch (stop_i % 6)
- {
- case 0:
- stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
- break;
- case 1:
- stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
- break;
- case 2:
- stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
- break;
- case 3:
- stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
- break;
- case 4:
- stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
- break;
- case 5:
- stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
- break;
- default:
- break;
- }
+ double start_f = start_h * 6. - start_i;
+ double start_q = 1. - start_f;
- Point<3> gradient_start_point_3d, gradient_stop_point_3d;
-
- gradient_start_point_3d[0] = gradient_param[0];
- gradient_start_point_3d[1] = gradient_param[1];
- gradient_start_point_3d[2] = gradient_param[4];
-
- gradient_stop_point_3d[0] = gradient_param[2];
- gradient_stop_point_3d[1] = gradient_param[3];
- gradient_stop_point_3d[2] = gradient_param[5];
-
- Point<2> gradient_start_point = svg_project_point(gradient_start_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
- Point<2> gradient_stop_point = svg_project_point(gradient_stop_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
-
- // define linear gradient
- out << " <linearGradient id=\"" << triangle_counter << "\" gradientUnits=\"userSpaceOnUse\" "
- << "x1=\""
- << static_cast<unsigned int>(.5 + ((gradient_start_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << "\" "
- << "y1=\""
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_start_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << "\" "
- << "x2=\""
- << static_cast<unsigned int>(.5 + ((gradient_stop_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << "\" "
- << "y2=\""
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_stop_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << "\""
- << ">" << '\n'
- << " <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
- << " <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
- << " </linearGradient>" << '\n';
-
- // draw current triangle
- double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- double x3 = cell->projected_center[0];
- double y3 = cell->projected_center[1];
-
- switch (triangle_index)
- {
- case 0:
- x1 = cell->projected_vertices[0][0], y1 = cell->projected_vertices[0][1], x2 = cell->projected_vertices[1][0], y2 = cell->projected_vertices[1][1];
- break;
- case 1:
- x1 = cell->projected_vertices[1][0], y1 = cell->projected_vertices[1][1], x2 = cell->projected_vertices[3][0], y2 = cell->projected_vertices[3][1];
- break;
- case 2:
- x1 = cell->projected_vertices[3][0], y1 = cell->projected_vertices[3][1], x2 = cell->projected_vertices[2][0], y2 = cell->projected_vertices[2][1];
- break;
- case 3:
- x1 = cell->projected_vertices[2][0], y1 = cell->projected_vertices[2][1], x2 = cell->projected_vertices[0][0], y2 = cell->projected_vertices[0][1];
- break;
- default:
- break;
- }
+ double stop_f = stop_h * 6. - stop_i;
+ double stop_q = 1. - stop_f;
- out << " <path d=\"M "
- << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << ' '
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << " L "
- << static_cast<unsigned int>(.5 + ((x2 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << ' '
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y2 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << " L "
- << static_cast<unsigned int>(.5 + ((x3 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << ' '
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y3 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << " L "
- << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
- << ' '
- << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
- << "\" style=\"stroke:black; fill:url(#" << triangle_counter << "); stroke-width:" << flags.line_thickness << "\"/>" << '\n';
-
- triangle_counter++;
- }
- }
+ switch (start_i % 6)
+ {
+ case 0:
+ start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
+ break;
+ case 1:
+ start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
+ break;
+ case 2:
+ start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
+ break;
+ case 3:
+ start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
+ break;
+ case 4:
+ start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
+ break;
+ case 5:
+ start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
+ break;
+ default:
+ break;
+ }
+ switch (stop_i % 6)
+ {
+ case 0:
+ stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
+ break;
+ case 1:
+ stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
+ break;
+ case 2:
+ stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
+ break;
+ case 3:
+ stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
+ break;
+ case 4:
+ stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
+ break;
+ case 5:
+ stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
+ break;
+ default:
+ break;
+ }
-// draw the colorbar
- if (flags.draw_colorbar)
- {
- out << '\n' << " <!-- colorbar -->" << '\n';
+ Point<3> gradient_start_point_3d, gradient_stop_point_3d;
+
+ gradient_start_point_3d[0] = gradient_param[0];
+ gradient_start_point_3d[1] = gradient_param[1];
+ gradient_start_point_3d[2] = gradient_param[4];
+
+ gradient_stop_point_3d[0] = gradient_param[2];
+ gradient_stop_point_3d[1] = gradient_param[3];
+ gradient_stop_point_3d[2] = gradient_param[5];
+
+ Point<2> gradient_start_point = svg_project_point(gradient_start_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
+ Point<2> gradient_stop_point = svg_project_point(gradient_stop_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
+
+ // define linear gradient
+ out << " <linearGradient id=\"" << triangle_counter << "\" gradientUnits=\"userSpaceOnUse\" "
+ << "x1=\""
+ << static_cast<unsigned int>(.5 + ((gradient_start_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << "\" "
+ << "y1=\""
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_start_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << "\" "
+ << "x2=\""
+ << static_cast<unsigned int>(.5 + ((gradient_stop_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << "\" "
+ << "y2=\""
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_stop_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << "\""
+ << ">" << '\n'
+ << " <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
+ << " <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
+ << " </linearGradient>" << '\n';
+
+ // draw current triangle
+ double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ double x3 = cell->projected_center[0];
+ double y3 = cell->projected_center[1];
+
+ switch (triangle_index)
+ {
+ case 0:
+ x1 = cell->projected_vertices[0][0], y1 = cell->projected_vertices[0][1], x2 = cell->projected_vertices[1][0], y2 = cell->projected_vertices[1][1];
+ break;
+ case 1:
+ x1 = cell->projected_vertices[1][0], y1 = cell->projected_vertices[1][1], x2 = cell->projected_vertices[3][0], y2 = cell->projected_vertices[3][1];
+ break;
+ case 2:
+ x1 = cell->projected_vertices[3][0], y1 = cell->projected_vertices[3][1], x2 = cell->projected_vertices[2][0], y2 = cell->projected_vertices[2][1];
+ break;
+ case 3:
+ x1 = cell->projected_vertices[2][0], y1 = cell->projected_vertices[2][1], x2 = cell->projected_vertices[0][0], y2 = cell->projected_vertices[0][1];
+ break;
+ default:
+ break;
+ }
- unsigned int element_height = static_cast<unsigned int>(((height/100.) * (71. - 2.*margin_in_percent)) / 4);
- unsigned int element_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
+ out << " <path d=\"M "
+ << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << ' '
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << " L "
+ << static_cast<unsigned int>(.5 + ((x2 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << ' '
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y2 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << " L "
+ << static_cast<unsigned int>(.5 + ((x3 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << ' '
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y3 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << " L "
+ << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+ << ' '
+ << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+ << "\" style=\"stroke:black; fill:url(#" << triangle_counter << "); stroke-width:" << flags.line_thickness << "\"/>" << '\n';
+
+ triangle_counter++;
+ }
+ }
- additional_width = 0;
- if (!flags.margin) additional_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
- for (unsigned int index = 0; index < 4; index++)
- {
- double start_h = .667 - ((index+1) / 4.) * .667;
- double stop_h = .667 - (index / 4.) * .667;
+// draw the colorbar
+ if (flags.draw_colorbar)
+ {
+ out << '\n' << " <!-- colorbar -->" << '\n';
- unsigned int start_r = 0;
- unsigned int start_g = 0;
- unsigned int start_b = 0;
+ unsigned int element_height = static_cast<unsigned int>(((height/100.) * (71. - 2.*margin_in_percent)) / 4);
+ unsigned int element_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
- unsigned int stop_r = 0;
- unsigned int stop_g = 0;
- unsigned int stop_b = 0;
+ additional_width = 0;
+ if (!flags.margin) additional_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
- unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
- unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
+ for (unsigned int index = 0; index < 4; index++)
+ {
+ double start_h = .667 - ((index+1) / 4.) * .667;
+ double stop_h = .667 - (index / 4.) * .667;
- double start_f = start_h * 6. - start_i;
- double start_q = 1. - start_f;
+ unsigned int start_r = 0;
+ unsigned int start_g = 0;
+ unsigned int start_b = 0;
- double stop_f = stop_h * 6. - stop_i;
- double stop_q = 1. - stop_f;
+ unsigned int stop_r = 0;
+ unsigned int stop_g = 0;
+ unsigned int stop_b = 0;
- switch (start_i % 6)
- {
- case 0:
- start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
- break;
- case 1:
- start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
- break;
- case 2:
- start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
- break;
- case 3:
- start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
- break;
- case 4:
- start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
- break;
- case 5:
- start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
- break;
- default:
- break;
- }
+ unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
+ unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
- switch (stop_i % 6)
- {
- case 0:
- stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
- break;
- case 1:
- stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
- break;
- case 2:
- stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
- break;
- case 3:
- stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
- break;
- case 4:
- stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
- break;
- case 5:
- stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
- break;
- default:
- break;
- }
+ double start_f = start_h * 6. - start_i;
+ double start_q = 1. - start_f;
- // define gradient
- out << " <linearGradient id=\"colorbar_" << index << "\" gradientUnits=\"userSpaceOnUse\" "
- << "x1=\"" << width + additional_width << "\" "
- << "y1=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height << "\" "
- << "x2=\"" << width + additional_width << "\" "
- << "y2=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (4-index) * element_height << "\""
- << ">" << '\n'
- << " <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
- << " <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
- << " </linearGradient>" << '\n';
-
- // draw box corresponding to the gradient above
- out << " <rect"
- << " x=\"" << width + additional_width
- << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height
- << "\" width=\"" << element_width
- << "\" height=\"" << element_height
- << "\" style=\"stroke:black; stroke-width:2; fill:url(#colorbar_" << index << ")\"/>" << '\n';
- }
+ double stop_f = stop_h * 6. - stop_i;
+ double stop_q = 1. - stop_f;
- for (unsigned int index = 0; index < 5; index++)
- {
- out << " <text x=\"" << width + additional_width + static_cast<unsigned int>(1.5 * element_width)
- << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29) + (4.-index) * element_height + 30.) << "\""
- << " style=\"text-anchor:start; font-size:80; font-family:Helvetica";
+ switch (start_i % 6)
+ {
+ case 0:
+ start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
+ break;
+ case 1:
+ start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
+ break;
+ case 2:
+ start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
+ break;
+ case 3:
+ start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
+ break;
+ case 4:
+ start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
+ break;
+ case 5:
+ start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
+ break;
+ default:
+ break;
+ }
- if (index == 0 || index == 4) out << "; font-weight:bold";
+ switch (stop_i % 6)
+ {
+ case 0:
+ stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
+ break;
+ case 1:
+ stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
+ break;
+ case 2:
+ stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
+ break;
+ case 3:
+ stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
+ break;
+ case 4:
+ stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
+ break;
+ case 5:
+ stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
+ break;
+ default:
+ break;
+ }
- out << "\">" << (float)(((int)((z_min + index * (z_dimension / 4.))*10000))/10000.);
+ // define gradient
+ out << " <linearGradient id=\"colorbar_" << index << "\" gradientUnits=\"userSpaceOnUse\" "
+ << "x1=\"" << width + additional_width << "\" "
+ << "y1=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height << "\" "
+ << "x2=\"" << width + additional_width << "\" "
+ << "y2=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (4-index) * element_height << "\""
+ << ">" << '\n'
+ << " <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
+ << " <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
+ << " </linearGradient>" << '\n';
+
+ // draw box corresponding to the gradient above
+ out << " <rect"
+ << " x=\"" << width + additional_width
+ << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height
+ << "\" width=\"" << element_width
+ << "\" height=\"" << element_height
+ << "\" style=\"stroke:black; stroke-width:2; fill:url(#colorbar_" << index << ")\"/>" << '\n';
+ }
- if (index == 4) out << " max";
- if (index == 0) out << " min";
+ for (unsigned int index = 0; index < 5; index++)
+ {
+ out << " <text x=\"" << width + additional_width + static_cast<unsigned int>(1.5 * element_width)
+ << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29) + (4.-index) * element_height + 30.) << "\""
+ << " style=\"text-anchor:start; font-size:80; font-family:Helvetica";
- out << "</text>" << '\n';
- }
- }
+ if (index == 0 || index == 4) out << "; font-weight:bold";
- // finalize the svg file
- out << '\n' << "</svg>";
- out.flush();
+ out << "\">" << (float)(((int)((z_min + index * (z_dimension / 4.))*10000))/10000.);
-}
+ if (index == 4) out << " max";
+ if (index == 0) out << " min";
+ out << "</text>" << '\n';
+ }
+ }
+ // finalize the svg file
+ out << '\n' << "</svg>";
+ out.flush();
-template <int dim, int spacedim>
-void
-DataOutBase::
-write_deal_II_intermediate (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const Deal_II_IntermediateFlags &/*flags*/,
- std::ostream &out)
-{
- AssertThrow (out, ExcIO());
+ }
- // first write tokens indicating the
- // template parameters. we need this in
- // here because we may want to read in data
- // again even if we don't know in advance
- // the template parameters, see step-19
- out << dim << ' ' << spacedim << '\n';
-
- // then write a header
- out << "[deal.II intermediate format graphics data]" << '\n'
- << "[written by " << DEAL_II_PACKAGE_NAME << " " << DEAL_II_PACKAGE_VERSION << "]" << '\n'
- << "[Version: " << Deal_II_IntermediateFlags::format_version << "]" << '\n';
-
- out << data_names.size() << '\n';
- for (unsigned int i=0; i<data_names.size(); ++i)
- out << data_names[i] << '\n';
-
- out << patches.size() << '\n';
- for (unsigned int i=0; i<patches.size(); ++i)
- out << patches[i] << '\n';
-
- out << vector_data_ranges.size() << '\n';
- for (unsigned int i=0; i<vector_data_ranges.size(); ++i)
- out << std_cxx1x::get<0>(vector_data_ranges[i]) << ' '
- << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
- << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
-
- out << '\n';
- // make sure everything now gets to
- // disk
- out.flush ();
-}
+ template <int dim, int spacedim>
+ void
+ write_deal_II_intermediate (const std::vector<Patch<dim,spacedim> > &patches,
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const Deal_II_IntermediateFlags &/*flags*/,
+ std::ostream &out)
+ {
+ AssertThrow (out, ExcIO());
+
+ // first write tokens indicating the
+ // template parameters. we need this in
+ // here because we may want to read in data
+ // again even if we don't know in advance
+ // the template parameters, see step-19
+ out << dim << ' ' << spacedim << '\n';
+
+ // then write a header
+ out << "[deal.II intermediate format graphics data]" << '\n'
+ << "[written by " << DEAL_II_PACKAGE_NAME << " " << DEAL_II_PACKAGE_VERSION << "]" << '\n'
+ << "[Version: " << Deal_II_IntermediateFlags::format_version << "]" << '\n';
+
+ out << data_names.size() << '\n';
+ for (unsigned int i=0; i<data_names.size(); ++i)
+ out << data_names[i] << '\n';
+
+ out << patches.size() << '\n';
+ for (unsigned int i=0; i<patches.size(); ++i)
+ out << patches[i] << '\n';
+
+ out << vector_data_ranges.size() << '\n';
+ for (unsigned int i=0; i<vector_data_ranges.size(); ++i)
+ out << std_cxx1x::get<0>(vector_data_ranges[i]) << ' '
+ << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
+ << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
-std::pair<unsigned int, unsigned int>
-DataOutBase::
-determine_intermediate_format_dimensions (std::istream &input)
-{
- Assert (input, ExcIO());
+ out << '\n';
+ // make sure everything now gets to
+ // disk
+ out.flush ();
+ }
- unsigned int dim, spacedim;
- input >> dim >> spacedim;
- return std::make_pair (dim, spacedim);
-}
+ std::pair<unsigned int, unsigned int>
+ determine_intermediate_format_dimensions (std::istream &input)
+ {
+ Assert (input, ExcIO());
+ unsigned int dim, spacedim;
+ input >> dim >> spacedim;
-template <int dim, int spacedim>
-void
-DataOutBase::write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
- Table<2,double> &data_vectors)
-{
- // unlike in the main function, we
- // don't have here the data_names
- // field, so we initialize it with
- // the number of data sets in the
- // first patch. the equivalence of
- // these two definitions is checked
- // in the main function.
-
- // we have to take care, however, whether the
- // points are appended to the end of the
- // patch->data table
- const unsigned int n_data_sets
- =patches[0].points_are_available ? (patches[0].data.n_rows() - spacedim) : patches[0].data.n_rows();
-
- Assert (data_vectors.size()[0] == n_data_sets,
- ExcInternalError());
-
- // loop over all patches
- unsigned int next_value = 0;
- for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch != patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
-
- Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
- Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
- for (unsigned int i=0; i<patch->data.n_cols(); ++i, ++next_value)
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- data_vectors[data_set][next_value] = patch->data(data_set,i);
- }
+ return std::make_pair (dim, spacedim);
+ }
+} // namespace DataOutBase
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- Assert (data_vectors[data_set].size() == next_value,
- ExcInternalError());
-}
return create_xdmf_entry(data_filter, h5_filename, cur_time, comm);
}
+
+
template <int dim, int spacedim>
XDMFEntry DataOutInterface<dim,spacedim>::
-create_xdmf_entry (const DataOutFilter &data_filter, const std::string &h5_filename, const double cur_time, MPI_Comm comm) const
+create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
+ const std::string &h5_filename, const double cur_time, MPI_Comm comm) const
{
return create_xdmf_entry(data_filter, h5_filename, h5_filename, cur_time, comm);
}
+
+
template <int dim, int spacedim>
XDMFEntry DataOutInterface<dim,spacedim>::
-create_xdmf_entry (const DataOutFilter &data_filter, const std::string &h5_mesh_filename, const std::string &h5_solution_filename, const double cur_time, MPI_Comm comm) const
+create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
+ const std::string &h5_mesh_filename,
+ const std::string &h5_solution_filename,
+ const double cur_time,
+ MPI_Comm comm) const
{
unsigned int local_node_cell_count[2], global_node_cell_count[2];
int myrank;
*/
template <int dim, int spacedim>
void DataOutInterface<dim,spacedim>::
-write_filtered_data (DataOutFilter &filtered_data) const
+write_filtered_data (DataOutBase::DataOutFilter &filtered_data) const
{
DataOutBase::write_filtered_data(get_patches(), get_dataset_names(),
get_vector_data_ranges(),
void DataOutBase::write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- DataOutFilter &filtered_data)
+ DataOutBase::DataOutFilter &filtered_data)
{
const unsigned int n_data_sets = data_names.size();
unsigned int n_node, n_cell;
template <int dim, int spacedim>
void DataOutInterface<dim,spacedim>::
-write_hdf5_parallel (const DataOutFilter &data_filter, const std::string &filename, MPI_Comm comm) const
+write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+ const std::string &filename, MPI_Comm comm) const
{
DataOutBase::write_hdf5_parallel(get_patches(), data_filter, filename, comm);
}
template <int dim, int spacedim>
void DataOutInterface<dim,spacedim>::
-write_hdf5_parallel (const DataOutFilter &data_filter, const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const
+write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+ const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const
{
DataOutBase::write_hdf5_parallel(get_patches(), data_filter, write_mesh_file, mesh_filename, solution_filename, comm);
}
template <int dim, int spacedim>
void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
- const DataOutFilter &data_filter,
+ const DataOutBase::DataOutFilter &data_filter,
const std::string &filename,
MPI_Comm comm)
{
template <int dim, int spacedim>
void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
- const DataOutFilter &data_filter,
+ const DataOutBase::DataOutFilter &data_filter,
const bool write_mesh_file,
const std::string &mesh_filename,
const std::string &solution_filename,
template <int dim, int spacedim>
void
DataOutInterface<dim,spacedim>::write (std::ostream &out,
- const OutputFormat output_format_) const
+ const DataOutBase::OutputFormat output_format_) const
{
- OutputFormat output_format = output_format_;
- if (output_format == default_format)
+ DataOutBase::OutputFormat output_format = output_format_;
+ if (output_format == DataOutBase::default_format)
output_format = default_fmt;
switch (output_format)
{
- case none:
+ case DataOutBase::none:
break;
- case dx:
+ case DataOutBase::dx:
write_dx (out);
break;
- case ucd:
+ case DataOutBase::ucd:
write_ucd (out);
break;
- case gnuplot:
+ case DataOutBase::gnuplot:
write_gnuplot (out);
break;
- case povray:
+ case DataOutBase::povray:
write_povray (out);
break;
- case eps:
+ case DataOutBase::eps:
write_eps (out);
break;
- case gmv:
+ case DataOutBase::gmv:
write_gmv (out);
break;
- case tecplot:
+ case DataOutBase::tecplot:
write_tecplot (out);
break;
- case tecplot_binary:
+ case DataOutBase::tecplot_binary:
write_tecplot_binary (out);
break;
- case vtk:
+ case DataOutBase::vtk:
write_vtk (out);
break;
- case vtu:
+ case DataOutBase::vtu:
write_vtu (out);
break;
- case svg:
+ case DataOutBase::svg:
write_svg (out);
break;
- case deal_II_intermediate:
+ case DataOutBase::deal_II_intermediate:
write_deal_II_intermediate (out);
break;
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_default_format(const OutputFormat fmt)
+DataOutInterface<dim,spacedim>::set_default_format(const DataOutBase::OutputFormat fmt)
{
- Assert (fmt != default_format, ExcNotImplemented());
+ Assert (fmt != DataOutBase::default_format, ExcNotImplemented());
default_fmt = fmt;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const DXFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::DXFlags &flags)
{
dx_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const UcdFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::UcdFlags &flags)
{
ucd_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const GnuplotFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::GnuplotFlags &flags)
{
gnuplot_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const PovrayFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::PovrayFlags &flags)
{
povray_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const EpsFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::EpsFlags &flags)
{
eps_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const GmvFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::GmvFlags &flags)
{
gmv_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const TecplotFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::TecplotFlags &flags)
{
tecplot_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const VtkFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::VtkFlags &flags)
{
vtk_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const SvgFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::SvgFlags &flags)
{
svg_flags = flags;
}
template <int dim, int spacedim>
void
-DataOutInterface<dim,spacedim>::set_flags (const Deal_II_IntermediateFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::Deal_II_IntermediateFlags &flags)
{
deal_II_intermediate_flags = flags;
}
template <int dim, int spacedim>
std::string
DataOutInterface<dim,spacedim>::
-default_suffix (const OutputFormat output_format) const
+default_suffix (const DataOutBase::OutputFormat output_format) const
{
- if (output_format == default_format)
+ if (output_format == DataOutBase::default_format)
return DataOutBase::default_suffix (default_fmt);
else
return DataOutBase::default_suffix (output_format);
DataOutInterface<dim,spacedim>::declare_parameters (ParameterHandler &prm)
{
prm.declare_entry ("Output format", "gnuplot",
- Patterns::Selection (get_output_format_names ()),
+ Patterns::Selection (DataOutBase::get_output_format_names ()),
"A name for the output format to be used");
prm.declare_entry("Subdivisions", "1", Patterns::Integer(),
"Number of subdivisions of each mesh cell");
prm.enter_subsection ("DX output parameters");
- DXFlags::declare_parameters (prm);
+ DataOutBase::DXFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("UCD output parameters");
- UcdFlags::declare_parameters (prm);
+ DataOutBase::UcdFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Gnuplot output parameters");
- GnuplotFlags::declare_parameters (prm);
+ DataOutBase::GnuplotFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Povray output parameters");
- PovrayFlags::declare_parameters (prm);
+ DataOutBase::PovrayFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Eps output parameters");
- EpsFlags::declare_parameters (prm);
+ DataOutBase::EpsFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Gmv output parameters");
- GmvFlags::declare_parameters (prm);
+ DataOutBase::GmvFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Tecplot output parameters");
- TecplotFlags::declare_parameters (prm);
+ DataOutBase::TecplotFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("Vtk output parameters");
- VtkFlags::declare_parameters (prm);
+ DataOutBase::VtkFlags::declare_parameters (prm);
prm.leave_subsection ();
prm.enter_subsection ("deal.II intermediate output parameters");
- Deal_II_IntermediateFlags::declare_parameters (prm);
+ DataOutBase::Deal_II_IntermediateFlags::declare_parameters (prm);
prm.leave_subsection ();
}
DataOutInterface<dim,spacedim>::parse_parameters (ParameterHandler &prm)
{
const std::string &output_name = prm.get ("Output format");
- default_fmt = parse_output_format (output_name);
+ default_fmt = DataOutBase::parse_output_format (output_name);
default_subdivisions = prm.get_integer ("Subdivisions");
prm.enter_subsection ("DX output parameters");
{
std::pair<unsigned int, unsigned int>
dimension_info
- = this->determine_intermediate_format_dimensions (in);
+ = DataOutBase::determine_intermediate_format_dimensions (in);
AssertThrow ((dimension_info.first == dim) &&
(dimension_info.second == spacedim),
ExcIncompatibleDimensions (dimension_info.first, dim,
-
-template <int dim, int spacedim>
-std::ostream &
-operator << (std::ostream &out,
- const DataOutBase::Patch<dim,spacedim> &patch)
+namespace DataOutBase
{
- // write a header line
- out << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]"
- << '\n';
-
- // then write all the data that is
- // in this patch
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- out << patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]] << ' ';
- out << '\n';
-
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- out << patch.neighbors[i] << ' ';
- out << '\n';
+ template <int dim, int spacedim>
+ std::ostream &
+ operator << (std::ostream &out,
+ const Patch<dim,spacedim> &patch)
+ {
+ // write a header line
+ out << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]"
+ << '\n';
- out << patch.patch_index << ' ' << patch.n_subdivisions
- << '\n';
+ // then write all the data that is
+ // in this patch
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ out << patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]] << ' ';
+ out << '\n';
- out << patch.points_are_available<<'\n';
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ out << patch.neighbors[i] << ' ';
+ out << '\n';
- out << patch.data.n_rows() << ' ' << patch.data.n_cols() << '\n';
- for (unsigned int i=0; i<patch.data.n_rows(); ++i)
- for (unsigned int j=0; j<patch.data.n_cols(); ++j)
- out << patch.data[i][j] << ' ';
- out << '\n';
- out << '\n';
+ out << patch.patch_index << ' ' << patch.n_subdivisions
+ << '\n';
- return out;
-}
+ out << patch.points_are_available<<'\n';
+ out << patch.data.n_rows() << ' ' << patch.data.n_cols() << '\n';
+ for (unsigned int i=0; i<patch.data.n_rows(); ++i)
+ for (unsigned int j=0; j<patch.data.n_cols(); ++j)
+ out << patch.data[i][j] << ' ';
+ out << '\n';
+ out << '\n';
+ return out;
+ }
-template <int dim, int spacedim>
-std::istream &
-operator >> (std::istream &in,
- DataOutBase::Patch<dim,spacedim> &patch)
-{
- Assert (in, ExcIO());
- // read a header line and compare
- // it to what we usually
- // write. skip all lines that
- // contain only blanks at the start
+ template <int dim, int spacedim>
+ std::istream &
+ operator >> (std::istream &in,
+ Patch<dim,spacedim> &patch)
{
- std::string header;
- do
- {
- getline (in, header);
- while ((header.size() != 0) &&
- (header[header.size()-1] == ' '))
- header.erase(header.size()-1);
- }
- while ((header == "") && in);
+ Assert (in, ExcIO());
- std::ostringstream s;
- s << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]";
+ // read a header line and compare
+ // it to what we usually
+ // write. skip all lines that
+ // contain only blanks at the start
+ {
+ std::string header;
+ do
+ {
+ getline (in, header);
+ while ((header.size() != 0) &&
+ (header[header.size()-1] == ' '))
+ header.erase(header.size()-1);
+ }
+ while ((header == "") && in);
- Assert (header == s.str(), ExcUnexpectedInput(s.str(),header));
- }
+ std::ostringstream s;
+ s << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]";
+
+ Assert (header == s.str(), ExcUnexpectedInput(s.str(),header));
+ }
- // then read all the data that is
- // in this patch
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- in >> patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]];
+ // then read all the data that is
+ // in this patch
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ in >> patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]];
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- in >> patch.neighbors[i];
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ in >> patch.neighbors[i];
- in >> patch.patch_index >> patch.n_subdivisions;
+ in >> patch.patch_index >> patch.n_subdivisions;
- in >> patch.points_are_available;
+ in >> patch.points_are_available;
- unsigned int n_rows, n_cols;
- in >> n_rows >> n_cols;
- patch.data.reinit (n_rows, n_cols);
- for (unsigned int i=0; i<patch.data.n_rows(); ++i)
- for (unsigned int j=0; j<patch.data.n_cols(); ++j)
- in >> patch.data[i][j];
+ unsigned int n_rows, n_cols;
+ in >> n_rows >> n_cols;
+ patch.data.reinit (n_rows, n_cols);
+ for (unsigned int i=0; i<patch.data.n_rows(); ++i)
+ for (unsigned int j=0; j<patch.data.n_cols(); ++j)
+ in >> patch.data[i][j];
- Assert (in, ExcIO());
+ Assert (in, ExcIO());
- return in;
+ return in;
+ }
}
-
// explicit instantiations
#include "data_out_base.inst"
#if deal_II_dimension <= deal_II_space_dimension
template class DataOutInterface<deal_II_dimension, deal_II_space_dimension>;
template class DataOutReader<deal_II_dimension, deal_II_space_dimension>;
- template struct DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension>;
+
+ namespace DataOutBase
+ \{
+ template struct Patch<deal_II_dimension, deal_II_space_dimension>;
template
std::ostream &
operator << (std::ostream &out,
- const DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension> &patch);
+ const Patch<deal_II_dimension, deal_II_space_dimension> &patch);
template
std::istream &
operator >> (std::istream &in,
- DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension> &patch);
+ Patch<deal_II_dimension, deal_II_space_dimension> &patch);
template
void
- DataOutBase::write_vtk (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_vtk (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const VtkFlags &flags,
template
void
- DataOutBase::write_vtu (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_vtu (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const VtkFlags &flags,
template
void
- DataOutBase::write_ucd (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_ucd (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const UcdFlags &flags,
template
void
- DataOutBase::write_dx (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_dx (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const DXFlags &flags,
template
void
- DataOutBase::write_gnuplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_gnuplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const GnuplotFlags &flags,
template
void
- DataOutBase::write_povray (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_povray (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const PovrayFlags &flags,
template
void
- DataOutBase::write_eps (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_eps (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const EpsFlags &flags,
template
void
- DataOutBase::write_gmv (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_gmv (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const GmvFlags &flags,
template
void
- DataOutBase::write_tecplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_tecplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const TecplotFlags &flags,
template
void
- DataOutBase::write_tecplot_binary (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_tecplot_binary (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const TecplotFlags &flags,
#if deal_II_space_dimension >1
template
void
- DataOutBase::write_svg (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_svg (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const SvgFlags &flags,
#endif
template
void
- DataOutBase::write_deal_II_intermediate (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+ write_deal_II_intermediate (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
const std::vector<std::string> &data_names,
const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
const Deal_II_IntermediateFlags &flags,
std::ostream &out);
+ \}
#endif
}
#include <deal.II/base/utilities.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/lac/vector_memory.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
#include <deal.II/base/multithread_info.h>
#include <cstddef>
// to errors
#ifdef DEAL_II_WITH_MPI
- // Start with Trilinos (need to do this before finalizing PETSc because it finalizes MPI.
- // Delete vectors from the pools:
+ // Start with the deal.II MPI vectors (need to do this before finalizing
+ // PETSc because it finalizes MPI). Delete vectors from the pools:
+ GrowingVectorMemory<parallel::distributed::Vector<double> >
+ ::release_unused_memory ();
+ GrowingVectorMemory<parallel::distributed::BlockVector<double> >
+ ::release_unused_memory ();
+ GrowingVectorMemory<parallel::distributed::Vector<float> >
+ ::release_unused_memory ();
+ GrowingVectorMemory<parallel::distributed::BlockVector<float> >
+ ::release_unused_memory ();
+
+ // Next with Trilinos:
# if defined(DEAL_II_WITH_TRILINOS)
GrowingVectorMemory<TrilinosWrappers::MPI::Vector>
::release_unused_memory ();
#include <cmath>
#include <limits>
+#include <algorithm>
+
DEAL_II_NAMESPACE_OPEN
const long double tolerance
= (runtime_one + long_double_eps != runtime_one
?
- fmax (double_eps / 100, long_double_eps * 5)
+ std::max (double_eps / 100, long_double_eps * 5)
:
double_eps * 5
);
const long double tolerance
= (runtime_one + long_double_eps != runtime_one
?
- fmax (double_eps / 100, long_double_eps * 5)
+ std::max (double_eps / 100, long_double_eps * 5)
:
double_eps * 5
);
const dealii::Tensor<1, spacedim> *shape_gradient_ptr =
&shape_gradients[snc][0];
- switch (shape_function_data[shape_function].single_nonzero_component_index)
- {
- case 0:
- {
- for (unsigned int q_point = 0;
- q_point < n_quadrature_points; ++q_point)
- curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
-
- break;
- }
-
- default:
- for (unsigned int q_point = 0;
- q_point < n_quadrature_points; ++q_point)
- curls[q_point][0] += value * (*shape_gradient_ptr)[0];
- }
+ Assert (shape_function_data[shape_function].single_nonzero_component >= 0,
+ ExcInternalError());
+ // we're in 2d, so the formula for the curl is simple:
+ if (shape_function_data[shape_function].single_nonzero_component_index == 0)
+ for (unsigned int q_point = 0;
+ q_point < n_quadrature_points; ++q_point)
+ curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
+ else
+ for (unsigned int q_point = 0;
+ q_point < n_quadrature_points; ++q_point)
+ curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
}
else
+ // we have multiple non-zero components in the shape functions. not
+ // all of them must necessarily be within the 2-component window
+ // this FEValuesViews::Vector object considers, however.
{
if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
{
break;
}
- default:
+ case 2:
+ {
for (unsigned int q_point = 0;
q_point < n_quadrature_points; ++q_point)
{
curls[q_point][0] += value * (*shape_gradient_ptr)[1];
curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
}
+ break;
+ }
+
+ default:
+ Assert (false, ExcInternalError());
}
}
else
+ // we have multiple non-zero components in the shape functions. not
+ // all of them must necessarily be within the 3-component window
+ // this FEValuesViews::Vector object considers, however.
{
if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
{
template<>
void
parallelogram (Triangulation<3> &tria,
- const Point<3> corners[3],
+ const Point<3> (&corners)[3],
const bool colorize)
{
Assert (false, ExcNotImplemented());
template<>
void
parallelogram (Triangulation<1> &tria,
- const Point<1> corners[1],
+ const Point<1> (&corners)[1],
const bool colorize)
{
Assert (false, ExcNotImplemented());
template<>
void
parallelogram (Triangulation<2> &tria,
- const Point<2> corners[2],
+ const Point<2> (&corners)[2],
const bool colorize)
{
std::vector<Point<2> > vertices (GeometryInfo<2>::vertices_per_cell);
template <template <int,int> class Container, int dim, int spacedim>
+#ifndef _MSC_VER
std::map<typename Container<dim-1,spacedim>::cell_iterator,
typename Container<dim,spacedim>::face_iterator>
+#else
+ typename ExtractBoundaryMesh<Container,dim,spacedim>::return_type
+#endif
extract_boundary_mesh (const Container<dim,spacedim> &volume_mesh,
Container<dim-1,spacedim> &surface_mesh,
const std::set<types::boundary_id> &boundary_ids)
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2001 - 2013 by the deal.II authors
+// Copyright (C) 2001 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
for (deal_II_space_dimension : SPACE_DIMENSIONS)
{
-
+
parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator
find_active_cell_around_point (const parallel::distributed::Triangulation<deal_II_space_dimension> &,
const Point<deal_II_space_dimension> &p);
-
+
std::pair<parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator, Point<deal_II_space_dimension> >
find_active_cell_around_point (const Mapping<deal_II_space_dimension> &,
const parallel::distributed::Triangulation<deal_II_space_dimension> &,
namespace GridTools \{
template
- std::map< Container<deal_II_dimension-1,deal_II_space_dimension>::cell_iterator,
+#ifndef _MSC_VER
+ std::map< Container<deal_II_dimension-1,deal_II_space_dimension>::cell_iterator,
Container<deal_II_dimension,deal_II_space_dimension>::face_iterator>
+#else
+ ExtractBoundaryMesh<Container,deal_II_dimension,deal_II_space_dimension>::return_type
+#endif
extract_boundary_mesh (const Container<deal_II_dimension, deal_II_space_dimension> &mesh,
Container<deal_II_dimension-1,deal_II_space_dimension> &boundary_mesh,
const std::set<types::boundary_id> &boundary_ids);
- template <>
- void
- DoFHandler<1>::
- compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
- {}
-
- template <>
- void
- DoFHandler<1,2>::
- compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
- {}
-
- template <>
- void
- DoFHandler<1,3>::
- compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
- {}
-
- template <>
+ template <int dim, int spacedim>
void
- DoFHandler<2>::
+ DoFHandler<dim,spacedim>::
compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
- {}
-
+ {
+ // this function should only be called for dim<3 where there are
+ // no quad dof identies. for dim>=3, the specialization below should
+ // take care of it
+ Assert (dim < 3, ExcInternalError());
+ }
template <>
void
- DoFHandler<2,3>::
- compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
- {}
-
-
-
- template<int dim, int spacedim>
- void
- DoFHandler<dim,spacedim>::
+ DoFHandler<3,3>::
compute_quad_dof_identities (std::vector<types::global_dof_index> &new_dof_indices) const
{
+ const int dim = 3;
+ const int spacedim = 3;
+
// we will mark quads that we
// have already treated, so first
// save and clear the user flags
for (; cell != endc; ++cell)
next_free_dof
- = dealii::internal::hp::DoFHandler::Implementation::template distribute_dofs_on_cell<spacedim> (cell,
+ = dealii::internal::hp::DoFHandler::Implementation::distribute_dofs_on_cell<spacedim> (cell,
next_free_dof);
number_cache.n_global_dofs = next_free_dof;
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
{}
+
template <typename number>
LAPACKFullMatrix<number>::LAPACKFullMatrix(
const size_type m,
{}
+
template <typename number>
LAPACKFullMatrix<number>::LAPACKFullMatrix(const LAPACKFullMatrix &M)
:
{}
+
template <typename number>
LAPACKFullMatrix<number> &
LAPACKFullMatrix<number>::operator = (const LAPACKFullMatrix<number> &M)
}
+
template <typename number>
template <typename number2>
LAPACKFullMatrix<number> &
LAPACKFullMatrix<number>::operator = (const FullMatrix<number2> &M)
{
- Assert (this->n_rows() == M.m(), ExcDimensionMismatch(this->n_rows(), M.m()));
+ Assert (this->n_rows() == M.n_rows(), ExcDimensionMismatch(this->n_rows(), M.n_rows()));
Assert (this->n_cols() == M.n(), ExcDimensionMismatch(this->n_cols(), M.n()));
for (size_type i=0; i<this->n_rows(); ++i)
for (size_type j=0; j<this->n_cols(); ++j)
}
+
template <typename number>
LAPACKFullMatrix<number> &
LAPACKFullMatrix<number>::operator = (const double d)
}
+
template <typename number>
void
LAPACKFullMatrix<number>::vmult (
}
+
template <typename number>
void
LAPACKFullMatrix<number>::Tvmult (
}
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mmult(LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert(C.state == matrix, ExcState(state));
+ Assert (this->n_cols() == B.n_rows(), ExcDimensionMismatch(this->n_cols(), B.n_rows()));
+ Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+ Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+ const int mm = this->n_rows();
+ const int nn = B.n_cols();
+ const int kk = this->n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ gemm("N", "N", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.values[0],
+ &kk, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mmult(FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert (this->n_cols() == B.n_rows(), ExcDimensionMismatch(this->n_cols(), B.n_rows()));
+ Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+ Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+ const int mm = this->n_rows();
+ const int nn = B.n_cols();
+ const int kk = this->n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ // since FullMatrix stores the matrix in transposed order compared to this
+ // matrix, compute B^T * A^T = (A * B)^T
+ gemm("T", "T", &nn, &mm, &kk, &alpha, &B.values[0], &kk, &this->values[0],
+ &mm, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::Tmmult(LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert(C.state == matrix, ExcState(state));
+ Assert (this->n_rows() == B.n_rows(), ExcDimensionMismatch(this->n_rows(), B.n_rows()));
+ Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+ Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+ const int mm = this->n_cols();
+ const int nn = B.n_cols();
+ const int kk = B.n_rows();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ gemm("T", "N", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.values[0],
+ &kk, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::Tmmult(FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert (this->n_rows() == B.n_rows(), ExcDimensionMismatch(this->n_rows(), B.n_rows()));
+ Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+ Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+ const int mm = this->n_cols();
+ const int nn = B.n_cols();
+ const int kk = B.n_rows();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ // since FullMatrix stores the matrix in transposed order compared to this
+ // matrix, compute B^T * A = (A^T * B)^T
+ gemm("T", "N", &nn, &mm, &kk, &alpha, &B.values[0], &kk, &this->values[0],
+ &kk, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mTmult(LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert(C.state == matrix, ExcState(state));
+ Assert (this->n_cols() == B.n_cols(), ExcDimensionMismatch(this->n_cols(), B.n_cols()));
+ Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+ Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+ const int mm = this->n_rows();
+ const int nn = B.n_rows();
+ const int kk = B.n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ gemm("N", "T", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.values[0],
+ &nn, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mTmult(FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert (this->n_cols() == B.n_cols(), ExcDimensionMismatch(this->n_cols(), B.n_cols()));
+ Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+ Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+ const int mm = this->n_rows();
+ const int nn = B.n_rows();
+ const int kk = B.n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ // since FullMatrix stores the matrix in transposed order compared to this
+ // matrix, compute B * A^T = (A * B^T)^T
+ gemm("N", "T", &nn, &mm, &kk, &alpha, &B.values[0], &nn, &this->values[0],
+ &mm, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::TmTmult(LAPACKFullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert(C.state == matrix, ExcState(state));
+ Assert (this->n_rows() == B.n_cols(), ExcDimensionMismatch(this->n_rows(), B.n_cols()));
+ Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+ Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+ const int mm = this->n_cols();
+ const int nn = B.n_rows();
+ const int kk = B.n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ gemm("T", "T", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.values[0],
+ &nn, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::TmTmult(FullMatrix<number> &C,
+ const LAPACKFullMatrix<number> &B,
+ const bool adding) const
+{
+ Assert(state == matrix, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert (this->n_rows() == B.n_cols(), ExcDimensionMismatch(this->n_rows(), B.n_cols()));
+ Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+ Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+ const int mm = this->n_cols();
+ const int nn = B.n_rows();
+ const int kk = B.n_cols();
+ const number alpha = 1.;
+ const number beta = (adding ? 1. : 0.);
+
+ // since FullMatrix stores the matrix in transposed order compared to this
+ // matrix, compute B * A = (A^T * B^T)^T
+ gemm("N", "N", &nn, &mm, &kk, &alpha, &B.values[0], &nn, &this->values[0],
+ &kk, &beta, &C(0,0), &nn);
+}
+
+
+
template <typename number>
void
LAPACKFullMatrix<number>::compute_lu_factorization()
}
+
template <typename number>
void
LAPACKFullMatrix<number>::compute_svd()
number *mvt = const_cast<number *> (&svd_vt->values[0]);
int info = 0;
- // see comment on this #if
- // below. Another reason to love Petsc
+ // see comment on this #if below. Another reason to love Petsc
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
- // First determine optimal
- // workspace size
+ // First determine optimal workspace size
work.resize(1);
int lwork = -1;
gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
}
+
template <typename number>
void
LAPACKFullMatrix<number>::compute_inverse_svd(const double threshold)
}
+
template <typename number>
void
LAPACKFullMatrix<number>::invert()
}
+
template <typename number>
void
LAPACKFullMatrix<number>::apply_lu_factorization(Vector<number> &v,
}
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::apply_lu_factorization(LAPACKFullMatrix<number> &B,
+ const bool transposed) const
+{
+ Assert(state == lu, ExcState(state));
+ Assert(B.state == matrix, ExcState(state));
+ Assert(this->n_rows() == this->n_cols(), LACExceptions::ExcNotQuadratic());
+
+ const char *trans = transposed ? &T : &N;
+ const int nn = this->n_cols();
+ const int kk = B.n_cols();
+ const number *values = &this->values[0];
+ int info = 0;
+
+ getrs(trans, &nn, &kk, values, &nn, &ipiv[0], &B.values[0], &nn, &info);
+
+ AssertThrow(info == 0, ExcInternalError());
+}
+
+
+
template <typename number>
void
LAPACKFullMatrix<number>::compute_eigenvalues(
// Optimal workspace query:
- // The LAPACK routine DGEEV requires
- // a sufficient large workspace variable,
+ // The LAPACK routine DGEEV requires a sufficient large workspace variable,
// minimum requirement is
// work.size>=4*nn.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
+ // However, to improve performance, a somewhat larger workspace may be
+ // needed.
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
+ // SOME implementations of the LAPACK routine provide a workspace query
+ // call,
// info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
+ // which returns an optimal value for the size of the workspace array (the
+ // PETSc 2.3.0 implementation does NOT provide this functionality!).
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+ // query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
&wr[0], &wi[0],
&vl[0], &nn, &vr[0], &nn,
&work[0], &lwork, &info);
- // geev returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // geev returns info=0 on success. Since we only queried the optimal size
+ // for work, everything else would not be acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 4*nn; // no query mode
&wr[0], &wi[0],
&vl[0], &nn, &vr[0], &nn,
&work[0], &lwork, &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a wrong argument. This should be internal.
Assert (info >=0, ExcInternalError());
//TODO:[GK] What if the QR method fails?
// Optimal workspace query:
- // The LAPACK routine ?SYEVX requires
- // a sufficient large workspace variable,
+ // The LAPACK routine ?SYEVX requires a sufficient large workspace variable,
// minimum requirement is
// work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
+ // However, to improve performance, a somewhat larger workspace may be
+ // needed.
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
+ // SOME implementations of the LAPACK routine provide a workspace query
+ // call,
// info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
+ // which returns an optimal value for the size of the workspace array (the
+ // PETSc 2.3.0 implementation does NOT provide this functionality!).
// define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
// disable the workspace query.
&n_eigenpairs, &wr[0], values_eigenvectors,
&nn, &work[0], &lwork, &iwork[0],
&ifail[0], &info);
- // syevx returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // syevx returns info=0 on success. Since we only queried the optimal size
+ // for work, everything else would not be acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
&nn, &work[0], &lwork, &iwork[0],
&ifail[0], &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a wrong argument. This should be internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
std::cerr << "LAPACK error in syevx" << std::endl;
// Optimal workspace query:
- // The LAPACK routine ?SYGVX requires
- // a sufficient large workspace variable,
+ // The LAPACK routine ?SYGVX requires a sufficient large workspace variable,
// minimum requirement is
// work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
+ // However, to improve performance, a somewhat larger workspace may be
+ // needed.
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
+ // SOME implementations of the LAPACK routine provide a workspace query
+ // call,
// info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
+ // which returns an optimal value for the size of the workspace array (the
+ // PETSc 2.3.0 implementation does NOT provide this functionality!).
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+ // query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
dummy, dummy, &abs_accuracy, &n_eigenpairs,
&wr[0], values_eigenvectors, &nn, &work[0],
&lwork, &iwork[0], &ifail[0], &info);
- // sygvx returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // sygvx returns info=0 on success. Since we only queried the optimal size
+ // for work, everything else would not be acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
// resize workspace arrays
work.resize(static_cast<size_type> (lwork));
- // Finally compute the generalized
- // eigenvalues.
+ // Finally compute the generalized eigenvalues.
sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
values_B, &nn, &lower_bound, &upper_bound,
dummy, dummy, &abs_accuracy, &n_eigenpairs,
&wr[0], values_eigenvectors, &nn, &work[0],
&lwork, &iwork[0], &ifail[0], &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a wrong argument. This should be internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
std::cerr << "LAPACK error in sygvx" << std::endl;
// Optimal workspace query:
- // The LAPACK routine DSYGV requires
- // a sufficient large workspace variable,
+ // The LAPACK routine DSYGV requires a sufficient large workspace variable,
// minimum requirement is
// work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
+ // However, to improve performance, a somewhat larger workspace may be
+ // needed.
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
+ // SOME implementations of the LAPACK routine provide a workspace query
+ // call,
// info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
+ // which returns an optimal value for the size of the workspace array (the
+ // PETSc 2.3.0 implementation does NOT provide this functionality!).
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+ // query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
sygv (&itype, jobz, uplo, &nn, values_A, &nn,
values_B, &nn,
&wr[0], &work[0], &lwork, &info);
- // sygv returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // sygv returns info=0 on success. Since we only queried the optimal size
+ // for work, everything else would not be acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 3*nn-1 > 1 ? 3*nn-1 : 1; // no query mode
// resize workspace array
work.resize((size_type) lwork);
- // Finally compute the generalized
- // eigenvalues.
+ // Finally compute the generalized eigenvalues.
sygv (&itype, jobz, uplo, &nn, values_A, &nn,
values_B, &nn,
&wr[0], &work[0], &lwork, &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a wrong argument. This should be internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2004 - 2013 by the deal.II authors
+// Copyright (C) 2004 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
FullMatrix::FullMatrix ()
{
- const int m=0, n=0;
- const int ierr
- = MatCreateSeqDense (PETSC_COMM_SELF, m, n, PETSC_NULL,
- &matrix);
-
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ // empty constructor generate an empty matrix
+ do_reinit (0, 0);
}
FullMatrix::FullMatrix (const size_type m,
}
-
const MPI_Comm &
FullMatrix::get_mpi_communicator () const
{
mg_constrained_dofs(&mg_c)
{}
+
template <class VECTOR>
MGTransferPrebuilt<VECTOR>::~MGTransferPrebuilt ()
{}
+template <class VECTOR>
+void MGTransferPrebuilt<VECTOR>::initialize_constraints (
+ const ConstraintMatrix &c, const MGConstrainedDoFs &mg_c)
+{
+ constraints = &c;
+ mg_constrained_dofs = &mg_c;
+}
+
+
+template <class VECTOR>
+void MGTransferPrebuilt<VECTOR>::clear ()
+{
+ sizes.resize(0);
+ prolongation_matrices.resize(0);
+ prolongation_sparsities.resize(0);
+ copy_indices.resize(0);
+ copy_indices_to_me.resize(0);
+ copy_indices_from_me.resize(0);
+ component_to_block_map.resize(0);
+ interface_dofs.resize(0);
+ constraints = 0;
+ mg_constrained_dofs = 0;
+}
+
+
template <class VECTOR>
void MGTransferPrebuilt<VECTOR>::prolongate (
const unsigned int to_level,
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
DataOutFaces<dim,DH>::DataOutFaces(const bool so)
:
surface_only(so)
-{}
+{
+ Assert (dim == DH::dimension,
+ ExcNotImplemented());
+}
void
DataOutFaces<dim,DH>::
build_one_patch (const FaceDescriptor *cell_and_face,
- internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
- DataOutBase::Patch<DH::dimension-1,DH::space_dimension> &patch)
+ internal::DataOutFaces::ParallelData<dimension, dimension> &data,
+ DataOutBase::Patch<dimension-1,space_dimension> &patch)
{
Assert (cell_and_face->first->is_locally_owned(),
ExcNotImplemented());
// on cells, not faces, so transform the face vertex to a cell vertex, that
// to a unit cell vertex and then, finally, that to the mapped vertex. In
// most cases this complicated procedure will be the identity.
- for (unsigned int vertex=0; vertex<GeometryInfo<DH::dimension-1>::vertices_per_cell; ++vertex)
+ for (unsigned int vertex=0; vertex<GeometryInfo<dimension-1>::vertices_per_cell; ++vertex)
patch.vertices[vertex] = data.mapping_collection[0].transform_unit_to_real_cell
(cell_and_face->first,
- GeometryInfo<DH::dimension>::unit_cell_vertex
+ GeometryInfo<dimension>::unit_cell_vertex
(GeometryInfo<dim>::face_to_cell_vertices
(cell_and_face->second,
vertex,
{
data.reinit_all_fe_values(this->dof_data, cell_and_face->first,
cell_and_face->second);
- const FEValuesBase<DH::dimension> &fe_patch_values
+ const FEValuesBase<dimension> &fe_patch_values
= data.get_present_fe_values (0);
const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
// store the intermediate points
- Assert(patch.space_dim==DH::dimension, ExcInternalError());
- const std::vector<Point<DH::dimension> > &q_points=fe_patch_values.get_quadrature_points();
+ Assert(patch.space_dim==dimension, ExcInternalError());
+ const std::vector<Point<dimension> > &q_points=fe_patch_values.get_quadrature_points();
// resize the patch.data member in order to have enough memory for the
// quadrature points as well
- patch.data.reinit(data.n_datasets+DH::dimension,
+ patch.data.reinit(data.n_datasets+dimension,
patch.data.size(1));
// set the flag indicating that for this cell the points are explicitly
// given
patch.points_are_available=true;
// copy points to patch.data
- for (unsigned int i=0; i<DH::dimension; ++i)
+ for (unsigned int i=0; i<dimension; ++i)
for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(patch.data.size(0)-DH::dimension+i,q)=q_points[q][i];
+ patch.data(patch.data.size(0)-dimension+i,q)=q_points[q][i];
// counter for data records
unsigned int offset=0;
// first fill dof_data
for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
{
- const FEValuesBase<DH::dimension> &fe_patch_values
+ const FEValuesBase<dimension> &fe_patch_values
= data.get_present_fe_values (dataset);
const unsigned int n_components
= fe_patch_values.get_fe().n_components();
Assert (cell_and_face->first->active(), ExcCellNotActiveForCellData());
const unsigned int cell_number
= std::distance (this->triangulation->begin_active(),
- typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(cell_and_face->first));
+ typename Triangulation<dimension,space_dimension>::active_cell_iterator(cell_and_face->first));
const double value
= this->cell_data[dataset]->get_cell_data_value (cell_number);
template <int dim, class DH>
void DataOutFaces<dim,DH>::build_patches (const unsigned int n_subdivisions_)
{
- build_patches (StaticMappingQ1<DH::dimension>::mapping, n_subdivisions_);
+ build_patches (StaticMappingQ1<dimension>::mapping, n_subdivisions_);
}
template <int dim, class DH>
-void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
+void DataOutFaces<dim,DH>::build_patches (const Mapping<dimension> &mapping,
const unsigned int n_subdivisions_)
{
// Check consistency of redundant template parameter
- Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
+ Assert (dim==dimension, ExcDimensionMismatch(dim, dimension));
const unsigned int n_subdivisions = (n_subdivisions_ != 0)
? n_subdivisions_
Assert (n_subdivisions >= 1,
ExcInvalidNumberOfSubdivisions(n_subdivisions));
- typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
+ typedef DataOut_DoFData<DH,dimension+1> BaseClass;
Assert (this->triangulation != 0,
typename BaseClass::ExcNoTriangulationSelected());
update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
update_flags |= update_quadrature_points;
- internal::DataOutFaces::ParallelData<DH::dimension, DH::space_dimension>
+ internal::DataOutFaces::ParallelData<dimension, space_dimension>
thread_data (n_datasets,
n_subdivisions,
n_postprocessor_outputs,
mapping,
this->get_finite_elements(),
update_flags);
- DataOutBase::Patch<DH::dimension-1,DH::space_dimension> sample_patch;
+ DataOutBase::Patch<dimension-1,space_dimension> sample_patch;
sample_patch.n_subdivisions = n_subdivisions;
sample_patch.data.reinit (n_datasets,
- Utilities::fixed_power<DH::dimension-1>(n_subdivisions+1));
+ Utilities::fixed_power<dimension-1>(n_subdivisions+1));
// now build the patches in parallel
WorkStream::run (&all_faces[0],
std_cxx1x::bind(&DataOutFaces<dim,DH>::build_one_patch,
this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
std_cxx1x::bind(&internal::DataOutFaces::
- append_patch_to_list<dim,DH::space_dimension>,
+ append_patch_to_list<dim,space_dimension>,
std_cxx1x::_1, std_cxx1x::ref(this->patches)),
thread_data,
sample_patch);
{
// simply find first active cell
// with a face on the boundary
- typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator cell = this->triangulation->begin_active();
+ typename Triangulation<dimension,space_dimension>::active_cell_iterator cell = this->triangulation->begin_active();
for (; cell != this->triangulation->end(); ++cell)
- for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+ for (unsigned int f=0; f<GeometryInfo<dimension>::faces_per_cell; ++f)
if (!surface_only || cell->face(f)->at_boundary())
return FaceDescriptor(cell, f);
FaceDescriptor face = old_face;
// first check whether the present cell has more faces on the boundary
- for (unsigned int f=face.second+1; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+ for (unsigned int f=face.second+1; f<GeometryInfo<dimension>::faces_per_cell; ++f)
if (!surface_only || face.first->face(f)->at_boundary())
// yup, that is so, so return it
{
// convert the iterator to an active_iterator and advance this to the next
// active cell
- typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell = face.first;
+ typename Triangulation<dimension,space_dimension>::active_cell_iterator active_cell = face.first;
// increase face pointer by one
++active_cell;
while (active_cell != this->triangulation->end())
{
// check all the faces of this active cell
- for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+ for (unsigned int f=0; f<GeometryInfo<dimension>::faces_per_cell; ++f)
if (!surface_only || active_cell->face(f)->at_boundary())
{
face.first = active_cell;
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
void
DataOutRotation<dim,DH>::
build_one_patch (const cell_iterator *cell,
- internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
- std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches)
+ internal::DataOutRotation::ParallelData<dimension, space_dimension> &data,
+ std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> > &patches)
{
if (dim == 3)
{
// which we will put points in the whole domain (not the rotationally
// reduced one in which the computation took place. for simplicity add the
// initial direction at the end again
- std::vector<Point<DH::dimension+1> > angle_directions (n_patches_per_circle+1);
+ std::vector<Point<dimension+1> > angle_directions (n_patches_per_circle+1);
for (unsigned int i=0; i<=n_patches_per_circle; ++i)
{
- angle_directions[i][DH::dimension-1] = std::cos(2*numbers::PI *
+ angle_directions[i][dimension-1] = std::cos(2*numbers::PI *
i/n_patches_per_circle);
- angle_directions[i][DH::dimension] = std::sin(2*numbers::PI *
+ angle_directions[i][dimension] = std::sin(2*numbers::PI *
i/n_patches_per_circle);
}
// first compute the vertices of the patch. note that they will have to
// be computed from the vertices of the cell, which has one dimension
// less, however.
- switch (DH::dimension)
+ switch (dimension)
{
case 1:
{
case 2:
{
for (unsigned int vertex=0;
- vertex<GeometryInfo<DH::dimension>::vertices_per_cell;
+ vertex<GeometryInfo<dimension>::vertices_per_cell;
++vertex)
{
- const Point<DH::dimension> v = (*cell)->vertex(vertex);
+ const Point<dimension> v = (*cell)->vertex(vertex);
// make sure that the radial variable does attain negative
// values
patches[angle].vertices[vertex] = v(0) * angle_directions[angle];
patches[angle].vertices[vertex][0] = v(1);
- patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell]
+ patches[angle].vertices[vertex+GeometryInfo<dimension>::vertices_per_cell]
= v(0) * angle_directions[angle+1];
- patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell][0]
+ patches[angle].vertices[vertex+GeometryInfo<dimension>::vertices_per_cell][0]
= v(1);
};
// first fill dof_data
for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
{
- const FEValuesBase<DH::dimension> &fe_patch_values
+ const FEValuesBase<dimension> &fe_patch_values
= data.get_present_fe_values(dataset);
const unsigned int n_components
= fe_patch_values.get_fe().n_components();
if (update_flags & update_quadrature_points)
data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
- std::vector<Point<DH::space_dimension> > dummy_normals;
+ std::vector<Point<space_dimension> > dummy_normals;
postprocessor->
compute_derived_quantities_scalar(data.patch_values,
data.patch_gradients,
if (update_flags & update_quadrature_points)
data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
- std::vector<Point<DH::space_dimension> > dummy_normals;
+ std::vector<Point<space_dimension> > dummy_normals;
postprocessor->
compute_derived_quantities_vector(data.patch_values_system,
data.patch_gradients_system,
component<this->dof_data[dataset]->n_output_variables;
++component)
{
- switch (DH::dimension)
+ switch (dimension)
{
case 1:
for (unsigned int x=0; x<n_points; ++x)
this->dof_data[dataset]->get_function_values (fe_patch_values,
data.patch_values);
- switch (DH::dimension)
+ switch (dimension)
{
case 1:
for (unsigned int x=0; x<n_points; ++x)
for (unsigned int component=0; component<n_components;
++component)
{
- switch (DH::dimension)
+ switch (dimension)
{
case 1:
for (unsigned int x=0; x<n_points; ++x)
ExcMessage("Cell must be active for cell data"));
const unsigned int cell_number
= std::distance (this->triangulation->begin_active(),
- typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(*cell));
+ typename Triangulation<dimension,space_dimension>::active_cell_iterator(*cell));
const double value
= this->cell_data[dataset]->get_cell_data_value (cell_number);
- switch (DH::dimension)
+ switch (dimension)
{
case 1:
for (unsigned int x=0; x<n_points; ++x)
{
// Check consistency of redundant
// template parameter
- Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
- typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
+ Assert (dim==dimension, ExcDimensionMismatch(dim, dimension));
+ typedef DataOut_DoFData<DH,dimension+1> BaseClass;
Assert (this->triangulation != 0,
typename BaseClass::ExcNoTriangulationSelected());
else
n_postprocessor_outputs[dataset] = 0;
- const MappingQ1<DH::dimension, DH::space_dimension> mapping;
- internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension>
+ const MappingQ1<dimension, space_dimension> mapping;
+ internal::DataOutRotation::ParallelData<dimension, space_dimension>
thread_data (n_datasets,
n_subdivisions, n_patches_per_circle,
n_postprocessor_outputs, mapping, this->get_finite_elements(),
update_flags);
- std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> >
+ std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> >
new_patches (n_patches_per_circle);
for (unsigned int i=0; i<new_patches.size(); ++i)
{
new_patches[i].n_subdivisions = n_subdivisions;
new_patches[i].data.reinit (n_datasets,
- Utilities::fixed_power<DH::dimension+1>(n_subdivisions+1));
+ Utilities::fixed_power<dimension+1>(n_subdivisions+1));
}
// now build the patches in parallel
std_cxx1x::bind(&DataOutRotation<dim,DH>::build_one_patch,
this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
std_cxx1x::bind(&internal::DataOutRotation
- ::append_patch_to_list<dim,DH::space_dimension>,
+ ::append_patch_to_list<dim,space_dimension>,
std_cxx1x::_1, std_cxx1x::ref(this->patches)),
thread_data,
new_patches);
// convert the iterator to an
// active_iterator and advance
// this to the next active cell
- typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell = cell;
+ typename Triangulation<dimension,space_dimension>::active_cell_iterator active_cell = cell;
++active_cell;
return active_cell;
}
-template <typename T>
-static inline T sqr (const T t)
+namespace
{
- return t*t;
+ template <typename T>
+ inline T sqr (const T t)
+ {
+ return t*t;
+ }
}
+// --------------- First the classes and functions that describe individual
+// --------------- derivatives
+namespace DerivativeApproximation
+{
+ namespace internal
+ {
+ /**
+ * The following class is used to describe the data needed to compute the
+ * finite difference approximation to the gradient on a cell. See the
+ * general documentation of this class for more information on
+ * implementational details.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+ template <int dim>
+ class Gradient
+ {
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which holds the derivative described by this
+ * class.
+ */
+ typedef Tensor<1,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef double ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the gradient, we
+ * choose the Euclidian norm of the gradient vector.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the first derivatives, no such thing is necessary, so this function
+ * is a no-op.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
+ };
-// static variables
-template <int dim>
-const UpdateFlags DerivativeApproximation::Gradient<dim>::update_flags = update_values;
-
-template <int dim>
-const UpdateFlags DerivativeApproximation::SecondDerivative<dim>::update_flags = update_gradients;
+ // static variables
+ template <int dim>
+ const UpdateFlags Gradient<dim>::update_flags = update_values;
-template <int dim>
-const UpdateFlags DerivativeApproximation::ThirdDerivative<dim>::update_flags = update_hessians;
+ template <int dim>
+ template <class InputVector, int spacedim>
+ inline
+ typename Gradient<dim>::ProjectedDerivative
+ Gradient<dim>::
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ if (fe_values.get_fe().n_components() == 1)
+ {
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_values (solution, values);
+ return values[0];
+ }
+ else
+ {
+ std::vector<Vector<double> > values
+ (1, Vector<double>(fe_values.get_fe().n_components()));
+ fe_values.get_function_values (solution, values);
+ return values[0](component);
+ }
+ }
-// Dummy structures and dummy function used for WorkStream
-namespace internal
-{
- namespace Assembler
- {
- struct Scratch
- {
- Scratch() {}
- };
- struct CopyData
+ template <int dim>
+ inline
+ double
+ Gradient<dim>::derivative_norm (const Derivative &d)
{
- CopyData() {}
- };
- }
-}
+ double s = 0;
+ for (unsigned int i=0; i<dim; ++i)
+ s += d[i]*d[i];
+ return std::sqrt(s);
+ }
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::Gradient<dim>::ProjectedDerivative
-DerivativeApproximation::Gradient<dim>::
-get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
-{
- if (fe_values.get_fe().n_components() == 1)
+ template <int dim>
+ inline
+ void
+ Gradient<dim>::symmetrize (Derivative &)
{
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_values (solution, values);
- return values[0];
+ // nothing to do here
}
- else
+
+
+
+ /**
+ * The following class is used to describe the data needed to compute the
+ * finite difference approximation to the second derivatives on a cell. See
+ * the general documentation of this class for more information on
+ * implementational details.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+ template <int dim>
+ class SecondDerivative
{
- std::vector<Vector<double> > values
- (1, Vector<double>(fe_values.get_fe().n_components()));
- fe_values.get_function_values (solution, values);
- return values[0](component);
- }
-}
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which holds the derivative described by this
+ * class.
+ */
+ typedef Tensor<2,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef Tensor<1,dim> ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the (symmetric)
+ * tensor of second derivatives, we choose the absolute value of the
+ * largest eigenvalue, which is the matrix norm associated to the $l_2$
+ * norm of vectors. It is also the largest value of the curvature of the
+ * solution.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the second derivatives, each entry of the tensor is set to the mean
+ * of its value and the value of the transpose element.
+ *
+ * Note that this function actually modifies its argument.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
+ };
+ template <int dim>
+ const UpdateFlags SecondDerivative<dim>::update_flags = update_gradients;
-template <int dim>
-inline
-double
-DerivativeApproximation::Gradient<dim>::derivative_norm (const Derivative &d)
-{
- double s = 0;
- for (unsigned int i=0; i<dim; ++i)
- s += d[i]*d[i];
- return std::sqrt(s);
-}
+ template <int dim>
+ template <class InputVector, int spacedim>
+ inline
+ typename SecondDerivative<dim>::ProjectedDerivative
+ SecondDerivative<dim>::
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ if (fe_values.get_fe().n_components() == 1)
+ {
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_gradients (solution, values);
+ return values[0];
+ }
+ else
+ {
+ std::vector<std::vector<ProjectedDerivative> > values
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ fe_values.get_function_gradients (solution, values);
+ return values[0][component];
+ };
+ }
-template <int dim>
-inline
-void
-DerivativeApproximation::Gradient<dim>::symmetrize (Derivative &)
-{
- // nothing to do here
-}
+ template <>
+ inline
+ double
+ SecondDerivative<1>::
+ derivative_norm (const Derivative &d)
+ {
+ return std::fabs (d[0][0]);
+ }
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::SecondDerivative<dim>::ProjectedDerivative
-DerivativeApproximation::SecondDerivative<dim>::
-get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
-{
- if (fe_values.get_fe().n_components() == 1)
+ template <>
+ inline
+ double
+ SecondDerivative<2>::
+ derivative_norm (const Derivative &d)
{
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_gradients (solution, values);
- return values[0];
+ // note that d should be a
+ // symmetric 2x2 tensor, so the
+ // eigenvalues are:
+ //
+ // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
+ //
+ // if the d_11=a, d_22=b,
+ // d_12=d_21=c
+ const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
+ 4*dealii::sqr(d[0][1]);
+ const double eigenvalues[2]
+ = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
+ 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
+ };
+
+ return std::max (std::fabs (eigenvalues[0]),
+ std::fabs (eigenvalues[1]));
}
- else
+
+
+
+ template <>
+ inline
+ double
+ SecondDerivative<3>::
+ derivative_norm (const Derivative &d)
{
- std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
- fe_values.get_function_gradients (solution, values);
- return values[0][component];
- };
-}
+ /*
+ compute the three eigenvalues of the tensor @p{d} and take the
+ largest. one could use the following maple script to generate C
+ code:
+
+ with(linalg);
+ readlib(C);
+ A:=matrix(3,3,[[a00,a01,a02],[a01,a11,a12],[a02,a12,a22]]);
+ E:=eigenvals(A);
+ EE:=vector(3,[E[1],E[2],E[3]]);
+ C(EE);
+
+ Unfortunately, with both optimized and non-optimized output, at some
+ places the code `sqrt(-1.0)' is emitted, and I don't know what
+ Maple intends to do with it. This happens both with Maple4 and
+ Maple5.
+
+ Fortunately, Roger Young provided the following Fortran code, which
+ is transcribed below to C. The code uses an algorithm that uses the
+ invariants of a symmetric matrix. (The translated algorithm is
+ augmented by a test for R>0, since R==0 indicates that all three
+ eigenvalues are equal.)
+
+
+ PROGRAM MAIN
+
+ C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
+ C (ROGER YOUNG, 2001)
+
+ IMPLICIT NONE
+
+ REAL*8 A11, A12, A13, A22, A23, A33
+ REAL*8 I1, J2, J3, AM
+ REAL*8 S11, S12, S13, S22, S23, S33
+ REAL*8 SS12, SS23, SS13
+ REAL*8 R,R3, XX,YY, THETA
+ REAL*8 A1,A2,A3
+ REAL*8 PI
+ PARAMETER (PI=3.141592653587932384D0)
+ REAL*8 A,B,C, TOL
+ PARAMETER (TOL=1.D-14)
+
+ C DEFINE A TEST MATRIX
+
+ A11 = -1.D0
+ A12 = 5.D0
+ A13 = 3.D0
+ A22 = -2.D0
+ A23 = 0.5D0
+ A33 = 4.D0
+
+
+ I1 = A11 + A22 + A33
+ AM = I1/3.D0
+
+ S11 = A11 - AM
+ S22 = A22 - AM
+ S33 = A33 - AM
+ S12 = A12
+ S13 = A13
+ S23 = A23
+
+ SS12 = S12*S12
+ SS23 = S23*S23
+ SS13 = S13*S13
+
+ J2 = S11*S11 + S22*S22 + S33*S33
+ J2 = J2 + 2.D0*(SS12 + SS23 + SS13)
+ J2 = J2/2.D0
+
+ J3 = S11**3 + S22**3 + S33**3
+ J3 = J3 + 3.D0*S11*(SS12 + SS13)
+ J3 = J3 + 3.D0*S22*(SS12 + SS23)
+ J3 = J3 + 3.D0*S33*(SS13 + SS23)
+ J3 = J3 + 6.D0*S12*S23*S13
+ J3 = J3/3.D0
+
+ R = SQRT(4.D0*J2/3.D0)
+ R3 = R*R*R
+ XX = 4.D0*J3/R3
+
+ YY = 1.D0 - DABS(XX)
+ IF(YY.LE.0.D0)THEN
+ IF(YY.GT.(-TOL))THEN
+ WRITE(6,*)'Equal roots: XX= ',XX
+ A = -(XX/DABS(XX))*SQRT(J2/3.D0)
+ B = AM + A
+ C = AM - 2.D0*A
+ WRITE(6,*)B,' (twice) ',C
+ STOP
+ ELSE
+ WRITE(6,*)'Error: XX= ',XX
+ STOP
+ ENDIF
+ ENDIF
+
+ THETA = (ACOS(XX))/3.D0
+
+ A1 = AM + R*COS(THETA)
+ A2 = AM + R*COS(THETA + 2.D0*PI/3.D0)
+ A3 = AM + R*COS(THETA + 4.D0*PI/3.D0)
+
+ WRITE(6,*)A1,A2,A3
+
+ STOP
+ END
+
+ */
+
+ const double am = trace(d) / 3.;
+
+ // s := d - trace(d) I
+ Tensor<2,3> s = d;
+ for (unsigned int i=0; i<3; ++i)
+ s[i][i] -= am;
+
+ const double ss01 = s[0][1] * s[0][1],
+ ss12 = s[1][2] * s[1][2],
+ ss02 = s[0][2] * s[0][2];
+
+ const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
+ + 2 * (ss01 + ss02 + ss12)) / 2.;
+ const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
+ + 3. * s[0][0] * (ss01 + ss02)
+ + 3. * s[1][1] * (ss01 + ss12)
+ + 3. * s[2][2] * (ss02 + ss12)
+ + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
+
+ const double R = std::sqrt (4. * J2 / 3.);
+
+ double EE[3] = { 0, 0, 0 };
+ // the eigenvalues are away from
+ // @p{am} in the order of R. thus,
+ // if R<<AM, then we have the
+ // degenerate case with three
+ // identical eigenvalues. check
+ // this first
+ if (R <= 1e-14*std::fabs(am))
+ EE[0] = EE[1] = EE[2] = am;
+ else
+ {
+ // at least two eigenvalues are
+ // distinct
+ const double R3 = R*R*R;
+ const double XX = 4. * J3 / R3;
+ const double YY = 1. - std::fabs(XX);
+
+ Assert (YY > -1e-14, ExcInternalError());
+
+ if (YY < 0)
+ {
+ // two roots are equal
+ const double a = (XX>0 ? -1. : 1.) * R / 2;
+ EE[0] = EE[1] = am + a;
+ EE[2] = am - 2.*a;
+ }
+ else
+ {
+ const double theta = std::acos(XX) / 3.;
+ EE[0] = am + R*std::cos(theta);
+ EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
+ EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
+ };
+ };
+ return std::max (std::fabs (EE[0]),
+ std::max (std::fabs (EE[1]),
+ std::fabs (EE[2])));
+ }
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<1>::
-derivative_norm (const Derivative &d)
-{
- return std::fabs (d[0][0]);
-}
+ template <int dim>
+ inline
+ double
+ SecondDerivative<dim>::
+ derivative_norm (const Derivative &)
+ {
+ // computing the spectral norm is
+ // not so simple in general. it is
+ // feasible for dim==3 as shown
+ // above, since then there are
+ // still closed form expressions of
+ // the roots of the characteristic
+ // polynomial, and they can easily
+ // be computed using
+ // maple. however, for higher
+ // dimensions, some other method
+ // needs to be employed. maybe some
+ // steps of the power method would
+ // suffice?
+ Assert (false, ExcNotImplemented());
+ return 0;
+ }
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<2>::
-derivative_norm (const Derivative &d)
-{
- // note that d should be a
- // symmetric 2x2 tensor, so the
- // eigenvalues are:
- //
- // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
- //
- // if the d_11=a, d_22=b,
- // d_12=d_21=c
- const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
- 4*dealii::sqr(d[0][1]);
- const double eigenvalues[2]
- = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
- 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
- };
- return std::max (std::fabs (eigenvalues[0]),
- std::fabs (eigenvalues[1]));
-}
+ template <int dim>
+ inline
+ void
+ SecondDerivative<dim>::symmetrize (Derivative &d)
+ {
+ // symmetrize non-diagonal entries
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=i+1; j<dim; ++j)
+ {
+ const double s = (d[i][j] + d[j][i]) / 2;
+ d[i][j] = d[j][i] = s;
+ };
+ }
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<3>::
-derivative_norm (const Derivative &d)
-{
- /*
- compute the three eigenvalues of the tensor @p{d} and take the
- largest. one could use the following maple script to generate C
- code:
-
- with(linalg);
- readlib(C);
- A:=matrix(3,3,[[a00,a01,a02],[a01,a11,a12],[a02,a12,a22]]);
- E:=eigenvals(A);
- EE:=vector(3,[E[1],E[2],E[3]]);
- C(EE);
-
- Unfortunately, with both optimized and non-optimized output, at some
- places the code `sqrt(-1.0)' is emitted, and I don't know what
- Maple intends to do with it. This happens both with Maple4 and
- Maple5.
-
- Fortunately, Roger Young provided the following Fortran code, which
- is transcribed below to C. The code uses an algorithm that uses the
- invariants of a symmetric matrix. (The translated algorithm is
- augmented by a test for R>0, since R==0 indicates that all three
- eigenvalues are equal.)
-
-
- PROGRAM MAIN
-
- C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
- C (ROGER YOUNG, 2001)
-
- IMPLICIT NONE
-
- REAL*8 A11, A12, A13, A22, A23, A33
- REAL*8 I1, J2, J3, AM
- REAL*8 S11, S12, S13, S22, S23, S33
- REAL*8 SS12, SS23, SS13
- REAL*8 R,R3, XX,YY, THETA
- REAL*8 A1,A2,A3
- REAL*8 PI
- PARAMETER (PI=3.141592653587932384D0)
- REAL*8 A,B,C, TOL
- PARAMETER (TOL=1.D-14)
-
- C DEFINE A TEST MATRIX
-
- A11 = -1.D0
- A12 = 5.D0
- A13 = 3.D0
- A22 = -2.D0
- A23 = 0.5D0
- A33 = 4.D0
-
-
- I1 = A11 + A22 + A33
- AM = I1/3.D0
-
- S11 = A11 - AM
- S22 = A22 - AM
- S33 = A33 - AM
- S12 = A12
- S13 = A13
- S23 = A23
-
- SS12 = S12*S12
- SS23 = S23*S23
- SS13 = S13*S13
-
- J2 = S11*S11 + S22*S22 + S33*S33
- J2 = J2 + 2.D0*(SS12 + SS23 + SS13)
- J2 = J2/2.D0
-
- J3 = S11**3 + S22**3 + S33**3
- J3 = J3 + 3.D0*S11*(SS12 + SS13)
- J3 = J3 + 3.D0*S22*(SS12 + SS23)
- J3 = J3 + 3.D0*S33*(SS13 + SS23)
- J3 = J3 + 6.D0*S12*S23*S13
- J3 = J3/3.D0
-
- R = SQRT(4.D0*J2/3.D0)
- R3 = R*R*R
- XX = 4.D0*J3/R3
-
- YY = 1.D0 - DABS(XX)
- IF(YY.LE.0.D0)THEN
- IF(YY.GT.(-TOL))THEN
- WRITE(6,*)'Equal roots: XX= ',XX
- A = -(XX/DABS(XX))*SQRT(J2/3.D0)
- B = AM + A
- C = AM - 2.D0*A
- WRITE(6,*)B,' (twice) ',C
- STOP
- ELSE
- WRITE(6,*)'Error: XX= ',XX
- STOP
- ENDIF
- ENDIF
-
- THETA = (ACOS(XX))/3.D0
-
- A1 = AM + R*COS(THETA)
- A2 = AM + R*COS(THETA + 2.D0*PI/3.D0)
- A3 = AM + R*COS(THETA + 4.D0*PI/3.D0)
-
- WRITE(6,*)A1,A2,A3
-
- STOP
- END
-
- */
-
- const double am = trace(d) / 3.;
-
- // s := d - trace(d) I
- Tensor<2,3> s = d;
- for (unsigned int i=0; i<3; ++i)
- s[i][i] -= am;
-
- const double ss01 = s[0][1] * s[0][1],
- ss12 = s[1][2] * s[1][2],
- ss02 = s[0][2] * s[0][2];
-
- const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
- + 2 * (ss01 + ss02 + ss12)) / 2.;
- const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
- + 3. * s[0][0] * (ss01 + ss02)
- + 3. * s[1][1] * (ss01 + ss12)
- + 3. * s[2][2] * (ss02 + ss12)
- + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
-
- const double R = std::sqrt (4. * J2 / 3.);
-
- double EE[3] = { 0, 0, 0 };
- // the eigenvalues are away from
- // @p{am} in the order of R. thus,
- // if R<<AM, then we have the
- // degenerate case with three
- // identical eigenvalues. check
- // this first
- if (R <= 1e-14*std::fabs(am))
- EE[0] = EE[1] = EE[2] = am;
- else
+ template <int dim>
+ class ThirdDerivative
{
- // at least two eigenvalues are
- // distinct
- const double R3 = R*R*R;
- const double XX = 4. * J3 / R3;
- const double YY = 1. - std::fabs(XX);
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which
+ * holds the derivative described
+ * by this class.
+ */
+ typedef Tensor<3,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef Tensor<2,dim> ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the (symmetric)
+ * tensor of second derivatives, we choose the absolute value of the
+ * largest eigenvalue, which is the matrix norm associated to the $l_2$
+ * norm of vectors. It is also the largest value of the curvature of the
+ * solution.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the second derivatives, each entry of the tensor is set to the mean
+ * of its value and the value of the transpose element.
+ *
+ * Note that this function actually modifies its argument.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
+ };
- Assert (YY > -1e-14, ExcInternalError());
+ template <int dim>
+ const UpdateFlags ThirdDerivative<dim>::update_flags = update_hessians;
- if (YY < 0)
+
+ template <int dim>
+ template <class InputVector, int spacedim>
+ inline
+ typename ThirdDerivative<dim>::ProjectedDerivative
+ ThirdDerivative<dim>::
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component)
{
- // two roots are equal
- const double a = (XX>0 ? -1. : 1.) * R / 2;
- EE[0] = EE[1] = am + a;
- EE[2] = am - 2.*a;
+ if (fe_values.get_fe().n_components() == 1)
+ {
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_hessians (solution, values);
+ return values[0];
+ }
+ else
+ {
+ std::vector<std::vector<ProjectedDerivative> > values
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ fe_values.get_function_hessians (solution, values);
+ return values[0][component];
+ };
}
- else
- {
- const double theta = std::acos(XX) / 3.;
- EE[0] = am + R*std::cos(theta);
- EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
- EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
- };
- };
-
- return std::max (std::fabs (EE[0]),
- std::max (std::fabs (EE[1]),
- std::fabs (EE[2])));
-}
-template <int dim>
-inline
-double
-DerivativeApproximation::SecondDerivative<dim>::
-derivative_norm (const Derivative &)
-{
- // computing the spectral norm is
- // not so simple in general. it is
- // feasible for dim==3 as shown
- // above, since then there are
- // still closed form expressions of
- // the roots of the characteristic
- // polynomial, and they can easily
- // be computed using
- // maple. however, for higher
- // dimensions, some other method
- // needs to be employed. maybe some
- // steps of the power method would
- // suffice?
- Assert (false, ExcNotImplemented());
- return 0;
-}
+ template <>
+ inline
+ double
+ ThirdDerivative<1>::
+ derivative_norm (const Derivative &d)
+ {
+ return std::fabs (d[0][0][0]);
+ }
-template <int dim>
-inline
-void
-DerivativeApproximation::SecondDerivative<dim>::symmetrize (Derivative &d)
-{
- // symmetrize non-diagonal entries
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=i+1; j<dim; ++j)
- {
- const double s = (d[i][j] + d[j][i]) / 2;
- d[i][j] = d[j][i] = s;
- };
-}
+ template <int dim>
+ inline
+ double
+ ThirdDerivative<dim>::
+ derivative_norm (const Derivative &d)
+ {
+ // return the Frobenius-norm. this is a
+ // member function of Tensor<rank_,dim>
+ return d.norm();
+ }
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::ThirdDerivative<dim>::ProjectedDerivative
-DerivativeApproximation::ThirdDerivative<dim>::
-get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
-{
- if (fe_values.get_fe().n_components() == 1)
+ template <int dim>
+ inline
+ void
+ ThirdDerivative<dim>::symmetrize (Derivative &d)
{
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_hessians (solution, values);
- return values[0];
+ // symmetrize non-diagonal entries
+
+ // first do it in the case, that i,j,k are
+ // pairwise different (which can onlky happen
+ // in dim >= 3)
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=i+1; j<dim; ++j)
+ for (unsigned int k=j+1; k<dim; ++k)
+ {
+ const double s = (d[i][j][k] +
+ d[i][k][j] +
+ d[j][i][k] +
+ d[j][k][i] +
+ d[k][i][j] +
+ d[k][j][i]) / 6;
+ d[i][j][k]
+ = d[i][k][j]
+ = d[j][i][k]
+ = d[j][k][i]
+ = d[k][i][j]
+ = d[k][j][i]
+ = s;
+ }
+ // now do the case, where two indices are
+ // equal
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=i+1; j<dim; ++j)
+ {
+ // case 1: index i (lower one) is
+ // double
+ const double s = (d[i][i][j] +
+ d[i][j][i] +
+ d[j][i][i] ) / 3;
+ d[i][i][j]
+ = d[i][j][i]
+ = d[j][i][i]
+ = s;
+
+ // case 2: index j (higher one) is
+ // double
+ const double t = (d[i][j][j] +
+ d[j][i][j] +
+ d[j][j][i] ) / 3;
+ d[i][j][j]
+ = d[j][i][j]
+ = d[j][j][i]
+ = t;
+ }
}
- else
+
+
+ template <int order, int dim>
+ class DerivativeSelector
{
- std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
- fe_values.get_function_hessians (solution, values);
- return values[0][component];
+ public:
+ /**
+ * typedef to select the DerivativeDescription corresponding to the
+ * <tt>order</tt>th derivative. In this general template we set an unvalid
+ * typedef to void, the real typedefs have to be specialized.
+ */
+ typedef void DerivDescr;
+
};
-}
+ template <int dim>
+ class DerivativeSelector<1,dim>
+ {
+ public:
+ typedef Gradient<dim> DerivDescr;
+ };
-template <>
-inline
-double
-DerivativeApproximation::ThirdDerivative<1>::
-derivative_norm (const Derivative &d)
-{
- return std::fabs (d[0][0][0]);
-}
+ template <int dim>
+ class DerivativeSelector<2,dim>
+ {
+ public:
+ typedef SecondDerivative<dim> DerivDescr;
+ };
+ template <int dim>
+ class DerivativeSelector<3,dim>
+ {
+ public:
-template <int dim>
-inline
-double
-DerivativeApproximation::ThirdDerivative<dim>::
-derivative_norm (const Derivative &d)
-{
- // return the Frobenius-norm. this is a
- // member function of Tensor<rank_,dim>
- return d.norm();
+ typedef ThirdDerivative<dim> DerivDescr;
+ };
+ }
}
-
-template <int dim>
-inline
-void
-DerivativeApproximation::ThirdDerivative<dim>::symmetrize (Derivative &d)
+// Dummy structures and dummy function used for WorkStream
+namespace DerivativeApproximation
{
- // symmetrize non-diagonal entries
-
- // first do it in the case, that i,j,k are
- // pairwise different (which can onlky happen
- // in dim >= 3)
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=i+1; j<dim; ++j)
- for (unsigned int k=j+1; k<dim; ++k)
- {
- const double s = (d[i][j][k] +
- d[i][k][j] +
- d[j][i][k] +
- d[j][k][i] +
- d[k][i][j] +
- d[k][j][i]) / 6;
- d[i][j][k]
- = d[i][k][j]
- = d[j][i][k]
- = d[j][k][i]
- = d[k][i][j]
- = d[k][j][i]
- = s;
- };
- // now do the case, where two indices are
- // equal
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=i+1; j<dim; ++j)
+ namespace internal
+ {
+ namespace Assembler
+ {
+ struct Scratch
{
- // case 1: index i (lower one) is
- // double
- const double s = (d[i][i][j] +
- d[i][j][i] +
- d[j][i][i] ) / 3;
- d[i][i][j]
- = d[i][j][i]
- = d[j][i][i]
- = s;
-
- // case 2: index j (higher one) is
- // double
- const double t = (d[i][j][j] +
- d[j][i][j] +
- d[j][j][i] ) / 3;
- d[i][j][j]
- = d[j][i][j]
- = d[j][j][i]
- = t;
+ Scratch() {}
};
+ struct CopyData
+ {
+ CopyData() {}
+ };
+ }
+ }
}
+// ------------------------------- now for the functions that do the
+// ------------------------------- actual work
-
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_gradient (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
+namespace DerivativeApproximation
{
- approximate_derivative<Gradient<dim>,dim> (mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
-}
+ namespace internal
+ {
+ /**
+ * Compute the derivative approximation on one cell. This computes the full
+ * derivative tensor.
+ */
+ template <class DerivativeDescription, int dim,
+ template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_cell (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ typename DerivativeDescription::Derivative &derivative)
+ {
+ QMidpoint<dim> midpoint_rule;
+
+ // create collection objects from
+ // single quadratures, mappings,
+ // and finite elements. if we have
+ // an hp DoFHandler,
+ // dof_handler.get_fe() returns a
+ // collection of which we do a
+ // shallow copy instead
+ const hp::QCollection<dim> q_collection (midpoint_rule);
+ const hp::FECollection<dim> fe_collection(dof_handler.get_fe());
+ const hp::MappingCollection<dim> mapping_collection (mapping);
+
+ hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
+ q_collection,
+ DerivativeDescription::update_flags |
+ update_quadrature_points);
+
+ // matrix Y=sum_i y_i y_i^T
+ Tensor<2,dim> Y;
+
+
+ // vector to hold iterators to all
+ // active neighbors of a cell
+ // reserve the maximal number of
+ // active neighbors
+ std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
+ active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
+ GeometryInfo<dim>::max_children_per_face);
+
+ // vector
+ // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
+ // or related type for higher
+ // derivatives
+ typename DerivativeDescription::Derivative projected_derivative;
+
+ // reinit fe values object...
+ x_fe_midpoint_value.reinit (cell);
+ const FEValues<dim> &fe_midpoint_value
+ = x_fe_midpoint_value.get_present_fe_values();
+
+ // ...and get the value of the
+ // projected derivative...
+ const typename DerivativeDescription::ProjectedDerivative
+ this_midpoint_value
+ = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+ solution,
+ component);
+ // ...and the place where it lives
+ const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
+
+ // loop over all neighbors and
+ // accumulate the difference
+ // quotients from them. note
+ // that things get a bit more
+ // complicated if the neighbor
+ // is more refined than the
+ // present one
+ //
+ // to make processing simpler,
+ // first collect all neighbor
+ // cells in a vector, and then
+ // collect the data from them
+ GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
+
+ // now loop over all active
+ // neighbors and collect the
+ // data we need
+ typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
+ neighbor_ptr = active_neighbors.begin();
+ for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
+ {
+ const typename DH<dim,spacedim>::active_cell_iterator
+ neighbor = *neighbor_ptr;
+
+ // reinit fe values object...
+ x_fe_midpoint_value.reinit (neighbor);
+ const FEValues<dim> &fe_midpoint_value
+ = x_fe_midpoint_value.get_present_fe_values();
+
+ // ...and get the value of the
+ // solution...
+ const typename DerivativeDescription::ProjectedDerivative
+ neighbor_midpoint_value
+ = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+ solution, component);
+
+ // ...and the place where it lives
+ const Point<dim>
+ neighbor_center = fe_midpoint_value.quadrature_point(0);
+
+
+ // vector for the
+ // normalized
+ // direction between
+ // the centers of two
+ // cells
+ Point<dim> y = neighbor_center - this_center;
+ const double distance = std::sqrt(y.square());
+ // normalize y
+ y /= distance;
+ // *** note that unlike in
+ // the docs, y denotes the
+ // normalized vector
+ // connecting the centers
+ // of the two cells, rather
+ // than the normal
+ // difference! ***
+
+ // add up the
+ // contribution of
+ // this cell to Y
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ Y[i][j] += y[i] * y[j];
+
+ // then update the sum
+ // of difference
+ // quotients
+ typename DerivativeDescription::ProjectedDerivative
+ projected_finite_difference
+ = (neighbor_midpoint_value -
+ this_midpoint_value);
+ projected_finite_difference /= distance;
+
+ typename DerivativeDescription::Derivative projected_derivative_update;
+ outer_product (projected_derivative_update,
+ y,
+ projected_finite_difference);
+ projected_derivative += projected_derivative_update;
+ };
+
+ // can we determine an
+ // approximation of the
+ // gradient for the present
+ // cell? if so, then we need to
+ // have passed over vectors y_i
+ // which span the whole space,
+ // otherwise we would not have
+ // all components of the
+ // gradient
+ AssertThrow (determinant(Y) != 0,
+ ExcInsufficientDirections());
+
+ // compute Y^-1 g
+ const Tensor<2,dim> Y_inverse = invert(Y);
+
+ contract (derivative, Y_inverse, projected_derivative);
+
+ // finally symmetrize the derivative
+ DerivativeDescription::symmetrize (derivative);
+ }
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_gradient (const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
-{
- approximate_derivative<Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
-}
+ /**
+ * Compute the derivative approximation on a given cell. Fill the @p
+ * derivative_norm vector with the norm of the computed derivative tensors
+ * on the cell.
+ */
+ template <class DerivativeDescription, int dim,
+ template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator> > const &cell,
+ const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ // if the cell is not locally owned, then there is nothing to do
+ if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
+ *std_cxx1x::get<1>(cell.iterators) = 0;
+ else
+ {
+ typename DerivativeDescription::Derivative derivative;
+ // call the function doing the actual
+ // work on this cell
+ approximate_cell<DerivativeDescription,dim,DH,InputVector>
+ (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
+ // evaluate the norm and fill the vector
+ //*derivative_norm_on_this_cell
+ *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
+ }
+ }
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_second_derivative (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
-{
- approximate_derivative<SecondDerivative<dim>,dim> (mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
-}
+ /**
+ * Kind of the main function of this class. It is called by the public entry
+ * points to this class with the correct template first argument and then
+ * simply calls the @p approximate function, after setting up several
+ * threads and doing some administration that is independent of the actual
+ * derivative to be computed.
+ *
+ * The @p component argument denotes which component of the solution vector
+ * we are to work on.
+ */
+ template <class DerivativeDescription, int dim,
+ template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_derivative (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component,
+ Vector<float> &derivative_norm)
+ {
+ Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
+ ExcInvalidVectorLength (derivative_norm.size(),
+ dof_handler.get_tria().n_active_cells()));
+ Assert (component < dof_handler.get_fe().n_components(),
+ ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
+
+ typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
+ Iterators;
+ SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
+ derivative_norm.begin())),
+ end(Iterators(dof_handler.end(),
+ derivative_norm.end()));
+
+ // There is no need for a copier because there is no conflict between threads
+ // to write in derivative_norm. Scratch and CopyData are also useless.
+ WorkStream::run(begin,
+ end,
+ static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
+ Assembler::Scratch const &, Assembler::CopyData &)> >
+ (std_cxx1x::bind(&approximate<DerivativeDescription,dim,DH,InputVector,spacedim>,
+ std_cxx1x::_1,
+ std_cxx1x::cref(mapping),
+ std_cxx1x::cref(dof_handler),
+ std_cxx1x::cref(solution),component)),
+ std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
+ internal::Assembler::Scratch (),internal::Assembler::CopyData ());
+ }
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_second_derivative (const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
-{
- approximate_derivative<SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
-}
+ } // namespace internal
+} // namespace DerivativeApproximation
-template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative_tensor (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- Tensor<order,dim> &derivative,
- const unsigned int component)
+
+// ------------------------ finally for the public interface of this namespace
+
+namespace DerivativeApproximation
{
- approximate_cell<typename DerivativeSelector<order,dim>::DerivDescr,dim,DH,InputVector>
- (mapping,
- dof,
- solution,
- component,
- cell,
- derivative);
-}
+ template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_gradient (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
+ {
+ internal::approximate_derivative<internal::Gradient<dim>,dim> (mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
+ }
+ template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_gradient (const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
+ {
+ internal::approximate_derivative<internal::Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
+ }
-template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative_tensor (const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- Tensor<order,dim> &derivative,
- const unsigned int component)
-{
- // just call the respective function with Q1
- // mapping
- approximate_derivative_tensor (StaticMappingQ1<dim>::mapping,
- dof,
- solution,
- cell,
- derivative,
- component);
-}
+ template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_second_derivative (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
+ {
+ internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
+ }
-template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component,
- Vector<float> &derivative_norm)
-{
- Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
- ExcInvalidVectorLength (derivative_norm.size(),
- dof_handler.get_tria().n_active_cells()));
- Assert (component < dof_handler.get_fe().n_components(),
- ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
-
- typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
- Iterators;
- SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
- derivative_norm.begin())),
- end(Iterators(dof_handler.end(),
- derivative_norm.end()));
-
- // There is no need for a copier because there is no conflict between threads
- // to write in derivative_norm. Scratch and CopyData are also useless.
- WorkStream::run(begin,
- end,
- static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
- internal::Assembler::Scratch const &,internal::Assembler::CopyData &)> >
- (std_cxx1x::bind(&DerivativeApproximation::template approximate<DerivativeDescription,dim,DH,
- InputVector,spacedim>,
- std_cxx1x::_1,
- std_cxx1x::cref(mapping),
- std_cxx1x::cref(dof_handler),
- std_cxx1x::cref(solution),component)),
- std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
- internal::Assembler::Scratch (),internal::Assembler::CopyData ());
-}
+ template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+ void
+ approximate_second_derivative (const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
+ {
+ internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
+ }
+ template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
+ void
+ approximate_derivative_tensor (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof,
+ const InputVector &solution,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ Tensor<order,dim> &derivative,
+ const unsigned int component)
+ {
+ internal::approximate_cell<typename internal::DerivativeSelector<order,dim>::DerivDescr,dim,DH,InputVector>
+ (mapping,
+ dof,
+ solution,
+ component,
+ cell,
+ derivative);
+ }
-template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator> > const &cell,
- const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component)
-{
- // if the cell is not locally owned, then there is nothing to do
- if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
- *std_cxx1x::get<1>(cell.iterators) = 0;
- else
- {
- typename DerivativeDescription::Derivative derivative;
- // call the function doing the actual
- // work on this cell
- DerivativeApproximation::template approximate_cell<DerivativeDescription,dim,DH,InputVector>
- (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
- // evaluate the norm and fill the vector
- //*derivative_norm_on_this_cell
- *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
- }
-}
+ template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
+ void
+ approximate_derivative_tensor (const DH<dim,spacedim> &dof,
+ const InputVector &solution,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ Tensor<order,dim> &derivative,
+ const unsigned int component)
+ {
+ // just call the respective function with Q1 mapping
+ approximate_derivative_tensor<dim,DH,InputVector,order,spacedim>
+ (StaticMappingQ1<dim>::mapping,
+ dof,
+ solution,
+ cell,
+ derivative,
+ component);
+ }
-template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_cell (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- typename DerivativeDescription::Derivative &derivative)
-{
- QMidpoint<dim> midpoint_rule;
-
- // create collection objects from
- // single quadratures, mappings,
- // and finite elements. if we have
- // an hp DoFHandler,
- // dof_handler.get_fe() returns a
- // collection of which we do a
- // shallow copy instead
- const hp::QCollection<dim> q_collection (midpoint_rule);
- const hp::FECollection<dim> fe_collection(dof_handler.get_fe());
- const hp::MappingCollection<dim> mapping_collection (mapping);
-
- hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
- q_collection,
- DerivativeDescription::update_flags |
- update_quadrature_points);
-
- // matrix Y=sum_i y_i y_i^T
- Tensor<2,dim> Y;
-
-
- // vector to hold iterators to all
- // active neighbors of a cell
- // reserve the maximal number of
- // active neighbors
- std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
- active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
- GeometryInfo<dim>::max_children_per_face);
-
- // vector
- // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
- // or related type for higher
- // derivatives
- typename DerivativeDescription::Derivative projected_derivative;
-
- // reinit fe values object...
- x_fe_midpoint_value.reinit (cell);
- const FEValues<dim> &fe_midpoint_value
- = x_fe_midpoint_value.get_present_fe_values();
-
- // ...and get the value of the
- // projected derivative...
- const typename DerivativeDescription::ProjectedDerivative
- this_midpoint_value
- = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
- solution,
- component);
- // ...and the place where it lives
- const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
-
- // loop over all neighbors and
- // accumulate the difference
- // quotients from them. note
- // that things get a bit more
- // complicated if the neighbor
- // is more refined than the
- // present one
- //
- // to make processing simpler,
- // first collect all neighbor
- // cells in a vector, and then
- // collect the data from them
- GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
-
- // now loop over all active
- // neighbors and collect the
- // data we need
- typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
- neighbor_ptr = active_neighbors.begin();
- for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
- {
- const typename DH<dim,spacedim>::active_cell_iterator
- neighbor = *neighbor_ptr;
-
- // reinit fe values object...
- x_fe_midpoint_value.reinit (neighbor);
- const FEValues<dim> &fe_midpoint_value
- = x_fe_midpoint_value.get_present_fe_values();
-
- // ...and get the value of the
- // solution...
- const typename DerivativeDescription::ProjectedDerivative
- neighbor_midpoint_value
- = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
- solution, component);
-
- // ...and the place where it lives
- const Point<dim>
- neighbor_center = fe_midpoint_value.quadrature_point(0);
-
-
- // vector for the
- // normalized
- // direction between
- // the centers of two
- // cells
- Point<dim> y = neighbor_center - this_center;
- const double distance = std::sqrt(y.square());
- // normalize y
- y /= distance;
- // *** note that unlike in
- // the docs, y denotes the
- // normalized vector
- // connecting the centers
- // of the two cells, rather
- // than the normal
- // difference! ***
-
- // add up the
- // contribution of
- // this cell to Y
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- Y[i][j] += y[i] * y[j];
-
- // then update the sum
- // of difference
- // quotients
- typename DerivativeDescription::ProjectedDerivative
- projected_finite_difference
- = (neighbor_midpoint_value -
- this_midpoint_value);
- projected_finite_difference /= distance;
-
- typename DerivativeDescription::Derivative projected_derivative_update;
- outer_product (projected_derivative_update,
- y,
- projected_finite_difference);
- projected_derivative += projected_derivative_update;
- };
- // can we determine an
- // approximation of the
- // gradient for the present
- // cell? if so, then we need to
- // have passed over vectors y_i
- // which span the whole space,
- // otherwise we would not have
- // all components of the
- // gradient
- AssertThrow (determinant(Y) != 0,
- ExcInsufficientDirections());
-
- // compute Y^-1 g
- const Tensor<2,dim> Y_inverse = invert(Y);
-
- contract (derivative, Y_inverse, projected_derivative);
-
- // finally symmetrize the derivative
- DerivativeDescription::symmetrize (derivative);
-}
-template <int dim, int order>
-double
-DerivativeApproximation::
-derivative_norm(const Tensor<order,dim> &derivative)
-{
- return DerivativeSelector<order,dim>::DerivDescr::derivative_norm(derivative);
-}
+ template <int dim, int order>
+ double
+ derivative_norm (const Tensor<order,dim> &derivative)
+ {
+ return internal::DerivativeSelector<order,dim>::DerivDescr::derivative_norm(derivative);
+ }
+
+}
// --------------------------- explicit instantiations ---------------------
for (deal_II_dimension : DIMENSIONS ; VEC : SERIAL_VECTORS ; DH : DOFHANDLER_TEMPLATES)
{
+ namespace DerivativeApproximation
+ \{
template
void
-DerivativeApproximation::
approximate_gradient<deal_II_dimension>
(const Mapping<deal_II_dimension> &mapping,
const DH<deal_II_dimension> &dof_handler,
template
void
-DerivativeApproximation::
approximate_gradient<deal_II_dimension>
(const DH<deal_II_dimension> &dof_handler,
const VEC &solution,
template
void
-DerivativeApproximation::
approximate_second_derivative<deal_II_dimension>
(const Mapping<deal_II_dimension> &mapping,
const DH<deal_II_dimension> &dof_handler,
template
void
-DerivativeApproximation::
approximate_second_derivative<deal_II_dimension>
(const DH<deal_II_dimension> &dof_handler,
const VEC &solution,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const Mapping<deal_II_dimension> & mapping,
const DH<deal_II_dimension> &dof_handler,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const Mapping<deal_II_dimension> & mapping,
const DH<deal_II_dimension> &dof_handler,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const Mapping<deal_II_dimension> & mapping,
const DH<deal_II_dimension> &dof_handler,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const DH<deal_II_dimension> &dof_handler,
const VEC &solution,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const DH<deal_II_dimension> &dof_handler,
const VEC &solution,
template
void
-DerivativeApproximation::
approximate_derivative_tensor<deal_II_dimension>
(const DH<deal_II_dimension> &dof_handler,
const VEC &solution,
Tensor<3,deal_II_dimension> &derivative,
const unsigned int component);
+ \}
}
for (deal_II_dimension : DIMENSIONS)
{
+ namespace DerivativeApproximation
+ \{
template
double
-DerivativeApproximation::
derivative_norm(const Tensor<1,deal_II_dimension> &derivative);
template
double
-DerivativeApproximation::
derivative_norm(const Tensor<2,deal_II_dimension> &derivative);
template
double
-DerivativeApproximation::
derivative_norm(const Tensor<3,deal_II_dimension> &derivative);
-
-
-// static variables
-//
-// on AIX, the linker is unhappy about some missing symbols. they
-// should really be there, but explicitly instantiating them will also
-// not hurt
-template
-const UpdateFlags
-DerivativeApproximation::Gradient<deal_II_dimension>::update_flags;
-
-template
-const UpdateFlags
-DerivativeApproximation::SecondDerivative<deal_II_dimension>::update_flags;
-template
-const UpdateFlags
-DerivativeApproximation::ThirdDerivative<deal_II_dimension>::update_flags;
+ \}
}
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1998 - 2013 by the deal.II authors
+// Copyright (C) 1998 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
*/
template <class FE>
ParallelData (const FE &fe,
- const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
- const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+ const dealii::hp::QCollection<dim-1> &face_quadratures,
+ const dealii::hp::MappingCollection<dim,spacedim> &mapping,
const bool need_quadrature_points,
const unsigned int n_solution_vectors,
const types::subdomain_id subdomain_id,
template <class FE>
ParallelData<DH>::
ParallelData (const FE &fe,
- const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
- const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+ const dealii::hp::QCollection<dim-1> &face_quadratures,
+ const dealii::hp::MappingCollection<dim, spacedim> &mapping,
const bool need_quadrature_points,
const unsigned int n_solution_vectors,
const types::subdomain_id subdomain_id,
#
ENABLE_TESTING()
+INCLUDE_DIRECTORIES(
+ ${CMAKE_BINARY_DIR}/include/
+ ${CMAKE_SOURCE_DIR}/include/
+ ${DEAL_II_BUNDLED_INCLUDE_DIRS}
+ ${DEAL_II_INCLUDE_DIRS}
+ )
+
# Use the first available build type (this prefers debug mode if available):
LIST(GET DEAL_II_BUILD_TYPES 0 _mybuild)
MESSAGE(STATUS "Setting up quick_tests in ${_mybuild} mode")
IF("${mpi_run}" STREQUAL "")
SET(_command ./${_target})
ELSE()
- SET(_command mpirun -n ${mpi_run} ./${_target})
+ SET(_command ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${mpi_run} ${MPIEXEC_PREFLAGS} ./${_target})
ENDIF()
ADD_CUSTOM_TARGET(${_target}.run
DEPENDS ${_target}
ENDFOREACH()
# Test whether thread affinity is well behaved
+IF (DEAL_II_WITH_THREADS)
make_quicktest("affinity" ${_mybuild} "")
+ENDIF()
# Test if MPI is configured correctly
IF (DEAL_II_WITH_MPI)
// ---------------------------------------------------------------------
#include <deal.II/grid/tria.h>
+#include <deal.II/base/multithread_info.h>
#include <stdio.h>
+
+#if defined(__linux__)
#include <sched.h>
+#include <sys/sysinfo.h>
+#endif
-int main ()
+bool getaffinity(unsigned int &bits_set,unsigned int &mask)
{
- // we need this, otherwise gcc will not link against deal.II
- dealii::Triangulation<2> test;
-
+ bits_set = 0;
+ mask = 0x00;
+
+#if defined(__linux__)
cpu_set_t my_set;
CPU_ZERO(&my_set);
if (ret!=0)
{
printf("sched_getaffinity() failed, return value: %d\n", ret);
- return -1;
+ return false;
}
-
- unsigned int bits_set = 0;//not supported on old kernels: CPU_COUNT(&my_set);
for (int i=0;i<CPU_SETSIZE;++i)
bits_set += CPU_ISSET(i,&my_set);
- if (bits_set==1)
+ mask = *(int*)(&my_set);
+#else
+ // sadly we don't have an implementation
+ // for mac/windows
+#endif
+ return true;
+}
+
+
+int main ()
+{
+ // we need this, otherwise gcc will not link against deal.II
+ dealii::Triangulation<2> test;
+
+ unsigned int bits_set, mask;
+ if (!getaffinity(bits_set, mask))
+ return 1;
+
+ unsigned int nprocs = dealii::multithread_info.n_cpus;
+ unsigned int tbbprocs = dealii::multithread_info.n_threads();
+ printf("aff_ncpus=%d, mask=%08X, nprocs=%d, tbb_threads=%d\n",
+ bits_set, mask, nprocs, tbbprocs );
+
+ if (bits_set !=0 && bits_set!=nprocs)
+ {
+ printf("Warning: sched_getaffinity() returns that we can only use %d out of %d CPUs.\n",bits_set, nprocs);
+ return 2;
+ }
+ if (nprocs != tbbprocs)
{
- printf("Warning: sched_getaffinity() returns that we can only use one CPU.\n");
- return 1;
+ printf("Warning: for some reason TBB only wants to use %d out of %d CPUs.\n",
+ tbbprocs, nprocs);
+ return 3;
}
- printf("ncpus=%d, mask=%08X\n", bits_set, *(unsigned int*)(&my_set));
+
+ return 0;
}
scratch_data &scratch,
copy_data &data)
{
- std::cout << "hello!" << std::endl;
-
- data.value +=(*it)*(*it);
+ data.value = (*it);
}
void copy(int & value, const copy_data &data)
}
void test2()
-{
- std::vector<int> v(3);
- v[0] = 3;
- v[1] = 5;
- v[2] = 1;
+{
+ const int maxi = 10000;
+ std::vector<int> v(maxi);
+ for (unsigned int i=0;i<v.size();++i)
+ v[i] = i+1;
int result = 0;
WorkStream::run(v.begin(),
v.end(),
scratch_data(), copy_data());
std::cout << "result: " << result << std::endl;
- if (result != (3*3+5*5+1*1))
+ if (result != maxi*(maxi+1)/2)
exit(2);
}
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2005 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// functionparser: check if you can change the expression in an existing object
+
+#include "../tests.h"
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/point.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/base/function_parser.h>
+
+
+int main ()
+{
+ initlog();
+
+ // Define some constants that will be used by the function parser
+ std::map<std::string, double> constants;
+ constants["pi"] = numbers::PI;
+
+ // Define the variables that will be used inside the expressions
+ std::string variables = "s,t";
+
+ FunctionParser<2> fp;
+ fp.initialize("s,t", "s*t+1", constants);
+
+ double value = fp.value(Point<2>(2.0,2.5));
+ Assert(abs(1.0+2.0*2.5 - value) < 1e-10, ExcMessage("wrong value"));
+
+ std::vector<std::string> expressions;
+ expressions.push_back("sin(2*mypi*x)+y");
+ constants["mypi"] = numbers::PI;
+ fp.initialize("x,y", expressions, constants);
+ double value1 = fp.value(Point<2>(1.0,2.5), 0);
+ Assert(abs(2.5 - value1) < 1e-10, ExcMessage("wrong value"));
+
+}
+
+
+
+
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2005 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// functionparser: TBB
+
+#include "../tests.h"
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/point.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/base/function_parser.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/work_stream.h>
+
+
+FunctionParser<2> fp;
+
+struct scratch_data
+{
+};
+
+struct copy_data
+{
+ int value;
+ copy_data():
+ value(0)
+ {}
+
+};
+
+
+void assemble(const std::vector<int>::iterator &it,
+ scratch_data &scratch,
+ copy_data &data)
+{
+ double s = *it;
+ double value = fp.value(Point<2>(s, 2.5));
+ Assert(abs(1.0+s*2.5 - value) < 1e-10, ExcMessage("wrong value"));
+ std::cout << data.value << std::endl;
+
+ data.value = (abs(1.0+s*2.5 - value) < 1e-10)?1:0;
+}
+
+void copy(int & value, const copy_data &data)
+{
+ value += data.value;
+}
+
+
+void test2()
+{
+ std::map<std::string, double> constants;
+ constants["c"]=1.0;
+ fp.initialize("s,t", "s*t+c", constants);
+
+ std::vector<int> v(10000);
+ for (unsigned int i=0;i<v.size();++i)
+ v[i] = i;
+
+ int result = 0;
+ WorkStream::run(v.begin(),
+ v.end(),
+ &assemble,
+ std_cxx1x::bind(©,
+ std_cxx1x::ref(result),
+ std_cxx1x::_1),
+ scratch_data(), copy_data());
+ std::cout << "result: " << result << std::endl;
+
+ Assert(result == v.size(), ExcMessage("uhuh!"));
+}
+
+
+int main ()
+{
+ initlog();
+
+ test2();
+}
+
+
+
+
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2007 - 2013 by the deal.II authors
+// Copyright (C) 2007 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
{
names[i] = std::string("comp");
}
-
- DataOutBase dout;
+
DataOutBase::DXFlags dxflags;
DataOutBase::GnuplotFlags gflags;
std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > vectors;
if (dim==2)
- dout.write_gnuplot(patches, names, vectors, gflags, out);
+ DataOutBase::write_gnuplot(patches, names, vectors, gflags, out);
else
- dout.write_dx(patches, names, vectors, dxflags, out);
+ DataOutBase::write_dx(patches, names, vectors, dxflags, out);
}
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2007 - 2013 by the deal.II authors
+// Copyright (C) 2007 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
names[i] = std::string("comp");
}
- DataOutBase dout;
DataOutBase::DXFlags dxflags;
DataOutBase::GnuplotFlags gflags;
std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > vectors;
if (dim==2)
- dout.write_gnuplot(patches, names, vectors, gflags, out);
+ DataOutBase::write_gnuplot(patches, names, vectors, gflags, out);
else
- dout.write_dx(patches, names, vectors, dxflags, out);
+ DataOutBase::write_dx(patches, names, vectors, dxflags, out);
}
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2008 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// test ThreadLocalStorage::clear
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+
+struct X
+{
+ X ()
+ :
+ i(1)
+ {};
+
+ int i;
+};
+
+Threads::ThreadLocalStorage<X> tls_data;
+
+
+void execute (Threads::Mutex &m)
+{
+ // check correct default initialization
+ bool exists;
+ int i = tls_data.get(exists).i;
+ Assert (i == 1, ExcInternalError());
+ Assert (exists == false, ExcInternalError());
+
+ // set value
+ tls_data.get(exists).i = 2;
+
+ // try again. should have existed this time around
+ i = tls_data.get(exists).i;
+ Assert (i == 2, ExcInternalError());
+ Assert (exists == true, ExcInternalError());
+
+ // wait for the barrier to clear
+ m.acquire ();
+ m.release ();
+
+ // at this point, the tls object should have been cleared and should
+ // be back at its original value
+ i = tls_data.get(exists).i;
+ Assert (i == 1, ExcInternalError());
+ Assert (exists == false, ExcInternalError());
+}
+
+
+void test ()
+{
+ const unsigned int N = 10;
+ Threads::Mutex m[N];
+
+ // start N threads with mutices locked
+ Threads::ThreadGroup<> tg;
+ for (unsigned int i=0; i<N; ++i)
+ {
+ m[i].acquire ();
+ tg += Threads::new_thread (execute, m[i]);
+ }
+
+ // let threads work through their first part
+ sleep (3);
+
+ // then reset the thread local object and release the mutices so the
+ // threads can actually run to an end
+ tls_data.clear ();
+ for (unsigned int i=0; i<N; ++i)
+ m[i].release ();
+
+ // now make sure the threads all finish
+ tg.join_all ();
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+
+int main()
+{
+ std::ofstream logfile("output");
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test ();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2008 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// test ThreadLocalStorage::clear but using a sample object to
+// initialize the thread local storage
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+
+struct X
+{
+ X ()
+ :
+ i(1)
+ {};
+
+ int i;
+};
+
+X initializer ()
+{
+ X x;
+ x.i = 42;
+ return x;
+}
+
+X fourty_two = initializer();
+
+
+Threads::ThreadLocalStorage<X> tls_data(fourty_two);
+
+
+void execute (Threads::Mutex &m)
+{
+ // check correct default initialization
+ bool exists;
+ int i = tls_data.get(exists).i;
+ Assert (i == 42, ExcInternalError());
+ Assert (exists == false, ExcInternalError());
+
+ // set value
+ tls_data.get(exists).i = 2;
+
+ // try again. should have existed this time around
+ i = tls_data.get(exists).i;
+ Assert (i == 2, ExcInternalError());
+ Assert (exists == true, ExcInternalError());
+
+ // wait for the barrier to clear
+ m.acquire ();
+ m.release ();
+
+ // at this point, the tls object should have been cleared and should
+ // be back at its original value
+ i = tls_data.get(exists).i;
+ Assert (i == 42, ExcInternalError());
+ Assert (exists == false, ExcInternalError());
+}
+
+
+void test ()
+{
+ const unsigned int N = 10;
+ Threads::Mutex m[N];
+
+ // start N threads with mutices locked
+ Threads::ThreadGroup<> tg;
+ for (unsigned int i=0; i<N; ++i)
+ {
+ m[i].acquire ();
+ tg += Threads::new_thread (execute, m[i]);
+ }
+
+ // let threads work through their first part
+ sleep (3);
+
+ // then reset the thread local object and release the mutices so the
+ // threads can actually run to an end
+ tls_data.clear ();
+ for (unsigned int i=0; i<N; ++i)
+ m[i].release ();
+
+ // now make sure the threads all finish
+ tg.join_all ();
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+
+int main()
+{
+ std::ofstream logfile("output");
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test ();
+}
--- /dev/null
+
+DEAL::OK
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
{
public:
SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format);
+ const DataOutBase::OutputFormat output_format);
virtual void operator () (const DoFHandler<dim> &dof_handler,
const Vector<double> &solution) const;
private:
const std::string output_name_base;
- const typename DataOut<dim>::OutputFormat output_format;
+ const DataOutBase::OutputFormat output_format;
};
template <int dim>
SolutionOutput<dim>::
SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format)
+ const DataOutBase::OutputFormat output_format)
:
output_name_base (output_name_base),
output_format (output_format)
Evaluation::SolutionOutput<dim>
postprocessor2 (std::string("solution-")+solver_name,
- DataOut<dim>::gnuplot);
+ DataOutBase::gnuplot);
std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
postprocessor_list.push_back (&postprocessor1);
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
<< this->refinement_cycle
<< ".gnuplot"
<< std::ends;
- data_out.write (deallog.get_file_stream(), DataOut<dim>::gnuplot);
+ data_out.write (deallog.get_file_stream(), DataOutBase::gnuplot);
}
<< this->refinement_cycle
<< ".gnuplot"
<< std::ends;
- data_out.write (deallog.get_file_stream(), DataOut<dim>::gnuplot);
+ data_out.write (deallog.get_file_stream(), DataOutBase::gnuplot);
}
Triangulation<dim> tr;
GridGenerator::hyper_cube(tr);
- FE_Nedelec<dim> fe(3);
+ FESystem<dim> fe(FE_Q<dim>(2), dim);
test(tr, fe);
}
-DEAL::FE=FESystem<2>[FE_Q<2>(1)^2]
-DEAL:: curls[q]= -2.00
-DEAL:: grads[q]= 2.00 4.00 2.00 4.00
-DEAL:: curls[q]= -2.00
-DEAL:: grads[q]= 2.00 4.00 2.00 4.00
-DEAL:: curls[q]= -2.00
-DEAL:: grads[q]= 2.00 4.00 2.00 4.00
-DEAL:: curls[q]= -2.00
-DEAL:: grads[q]= 2.00 4.00 2.00 4.00
-DEAL::FE=FESystem<3>[FE_Q<3>(1)^3]
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL:: curls[q]= -6.00 9.00 -3.00
-DEAL:: grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
+DEAL::FE=FESystem<2>[FE_Q<2>(2)^2]
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 8.33e-16
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 -1.11e-16
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 -6.66e-16
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 2.22e-16
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2007 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// like _28 but also test a non-primitive element.
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/fe/fe_nedelec.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/numerics/vector_tools.h>
+#include <deal.II/numerics/data_out.h>
+
+#include <fstream>
+
+
+class F : public Function<2>
+{
+public:
+ F() : Function<2>(2) {}
+
+ virtual void vector_value (const Point<2> &p,
+ Vector<double> &v) const
+ {
+ // make the function equal to (0,x^2)
+ v[0] = 0;
+ v[1] = p[0]*p[0];
+ }
+};
+
+
+
+Tensor<1,1> curl (const Tensor<2,2> &grads)
+{
+ return Point<1>(grads[1][0] - grads[0][1]);
+}
+
+
+Tensor<1,3> curl (const Tensor<2,3> &grads)
+{
+ return Point<3>(grads[2][1] - grads[1][2],
+ grads[0][2] - grads[2][0],
+ grads[1][0] - grads[0][1]);
+}
+
+
+
+template<int dim>
+void test (const Triangulation<dim> &tr,
+ const FiniteElement<dim> &fe,
+ const unsigned int degree)
+{
+ deallog << "FE=" << fe.get_name()
+ << std::endl;
+
+ DoFHandler<dim> dof(tr);
+ dof.distribute_dofs(fe);
+
+ Vector<double> fe_function(dof.n_dofs());
+ // set the elements of the vector in such a way that the function
+ // equals the vector function (0,x^2)
+ ConstraintMatrix cm;
+ cm.close ();
+ VectorTools::project (dof, cm, QGauss<2>(2+degree), F(), fe_function);
+
+ const QGauss<dim> quadrature(2);
+ FEValues<dim> fe_values (fe, quadrature,
+ update_values | update_gradients | update_q_points);
+ fe_values.reinit (dof.begin_active());
+
+ // let the FEValues object compute the
+ // divergences at quadrature points
+ std::vector<typename dealii::internal::CurlType<dim>::type> curls (quadrature.size());
+ std::vector<Tensor<2,dim> > grads (quadrature.size());
+ FEValuesExtractors::Vector extractor(0);
+ fe_values[extractor].get_function_curls (fe_function, curls);
+ fe_values[extractor].get_function_gradients (fe_function, grads);
+
+ // now compare
+ for (unsigned int q=0; q<quadrature.size(); ++q)
+ {
+ deallog << " curls[q]= " << curls[q] << std::endl
+ << " grads[q]= " << grads[q] << std::endl;
+ Assert ((curl(grads[q]) - curls[q]).norm()
+ <= 1e-10,
+ ExcInternalError());
+
+ // we know the function F=(0,x^2) and we chose an element with
+ // high enough degree to exactly represent this function, so the
+ // curl of this function should be
+ // curl F = d_x F_y - d_y F_x = 2x
+ // verify that this is true
+ Assert (std::fabs(curls[q][0] - 2*fe_values.quadrature_point(q)[0])
+ <= 1e-10,
+ ExcInternalError());
+ }
+}
+
+
+
+template<int dim>
+void test_hyper_cube()
+{
+ Triangulation<dim> tr;
+ GridGenerator::hyper_cube(tr);
+
+ for (unsigned int degree=2; degree<5; ++degree)
+ {
+ FE_Nedelec<dim> fe(degree);
+ test(tr, fe, degree);
+ }
+}
+
+
+int main()
+{
+ std::ofstream logfile ("output");
+ deallog << std::setprecision (3);
+
+ deallog.attach(logfile);
+ deallog.depth_console (0);
+ deallog.threshold_double(1.e-7);
+
+ test_hyper_cube<2>();
+}
--- /dev/null
+
+DEAL::FE=FE_Nedelec<2>(2)
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 -1.98e-16
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 4.45e-16
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 -2.00e-16
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 -3.38e-16
+DEAL::FE=FE_Nedelec<2>(3)
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 5.69e-17
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 1.29e-15
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 2.40e-15
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 6.52e-16
+DEAL::FE=FE_Nedelec<2>(4)
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 -1.06e-15
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 2.32e-15
+DEAL:: curls[q]= 0.423
+DEAL:: grads[q]= 0.00 0.00 0.423 1.64e-15
+DEAL:: curls[q]= 1.58
+DEAL:: grads[q]= 0.00 0.00 1.58 -2.01e-15
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2001 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/grid_out.h>
+
+#include <fstream>
+#include <iomanip>
+
+template<int dim>
+Point<dim> trans_func(Point<dim> & p);
+
+template<>
+Point<2> trans_func(Point<2> & p)
+{
+ Point<2> r(p(0)+p(1)*p(1),p(1));
+ return r;
+}
+template<>
+Point<3> trans_func(Point<3> & p)
+{
+ Point<3> r(p(0)+p(1)*p(1),p(1),p(2));
+ return r;
+}
+
+
+
+template <int dim>
+void test ()
+{
+ deallog << "dim = " << dim << std::endl;
+
+ Triangulation<dim> tria;
+ GridGenerator::hyper_cube(tria);
+ tria.refine_global(1);
+ tria.begin_active()->set_refine_flag();
+ tria.execute_coarsening_and_refinement();
+
+
+ deallog << "Unchanged grid:" << std::endl;
+ GridOut().write_gnuplot (tria, deallog.get_file_stream());
+
+ {
+ std::ofstream f("grid1");
+ GridOut().write_gnuplot (tria, f);
+ }
+
+ GridTools::transform(trans_func<dim>, tria);
+
+ deallog << "transformed grid:" << std::endl;
+ GridOut().write_gnuplot (tria, deallog.get_file_stream());
+ {
+ std::ofstream f("grid2");
+ GridOut().write_gnuplot (tria, f);
+ }
+}
+
+
+int main ()
+{
+ initlog();
+ deallog.depth_console(0);
+
+ test<2> ();
+ test<3> ();
+
+ return 0;
+}
+
--- /dev/null
+
+DEAL::dim = 2
+DEAL::Unchanged grid:
+0.500000 0.00000 1 0
+1.00000 0.00000 1 0
+1.00000 0.500000 1 0
+0.500000 0.500000 1 0
+0.500000 0.00000 1 0
+
+
+0.00000 0.500000 1 0
+0.500000 0.500000 1 0
+0.500000 1.00000 1 0
+0.00000 1.00000 1 0
+0.00000 0.500000 1 0
+
+
+0.500000 0.500000 1 0
+1.00000 0.500000 1 0
+1.00000 1.00000 1 0
+0.500000 1.00000 1 0
+0.500000 0.500000 1 0
+
+
+0.00000 0.00000 2 0
+0.250000 0.00000 2 0
+0.250000 0.250000 2 0
+0.00000 0.250000 2 0
+0.00000 0.00000 2 0
+
+
+0.250000 0.00000 2 0
+0.500000 0.00000 2 0
+0.500000 0.250000 2 0
+0.250000 0.250000 2 0
+0.250000 0.00000 2 0
+
+
+0.00000 0.250000 2 0
+0.250000 0.250000 2 0
+0.250000 0.500000 2 0
+0.00000 0.500000 2 0
+0.00000 0.250000 2 0
+
+
+0.250000 0.250000 2 0
+0.500000 0.250000 2 0
+0.500000 0.500000 2 0
+0.250000 0.500000 2 0
+0.250000 0.250000 2 0
+
+
+DEAL::transformed grid:
+0.500000 0.00000 1 0
+1.00000 0.00000 1 0
+1.25000 0.500000 1 0
+0.750000 0.500000 1 0
+0.500000 0.00000 1 0
+
+
+0.250000 0.500000 1 0
+0.750000 0.500000 1 0
+1.50000 1.00000 1 0
+1.00000 1.00000 1 0
+0.250000 0.500000 1 0
+
+
+0.750000 0.500000 1 0
+1.25000 0.500000 1 0
+2.00000 1.00000 1 0
+1.50000 1.00000 1 0
+0.750000 0.500000 1 0
+
+
+0.00000 0.00000 2 0
+0.250000 0.00000 2 0
+0.312500 0.250000 2 0
+0.0625000 0.250000 2 0
+0.00000 0.00000 2 0
+
+
+0.250000 0.00000 2 0
+0.500000 0.00000 2 0
+0.625000 0.250000 2 0
+0.312500 0.250000 2 0
+0.250000 0.00000 2 0
+
+
+0.0625000 0.250000 2 0
+0.312500 0.250000 2 0
+0.500000 0.500000 2 0
+0.250000 0.500000 2 0
+0.0625000 0.250000 2 0
+
+
+0.312500 0.250000 2 0
+0.625000 0.250000 2 0
+0.750000 0.500000 2 0
+0.500000 0.500000 2 0
+0.312500 0.250000 2 0
+
+
+DEAL::dim = 3
+DEAL::Unchanged grid:
+0.500000 0.00000 0.00000 1 0
+1.00000 0.00000 0.00000 1 0
+1.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+1.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 0.00000 1 0
+
+0.500000 0.00000 0.00000 1 0
+0.500000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.00000 0.500000 0.00000 1 0
+0.500000 0.500000 0.00000 1 0
+0.500000 0.500000 0.500000 1 0
+0.00000 0.500000 0.500000 1 0
+0.00000 0.500000 0.00000 1 0
+
+0.00000 1.00000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+0.500000 1.00000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+0.00000 1.00000 0.00000 1 0
+
+0.00000 0.500000 0.00000 1 0
+0.00000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+1.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 0.00000 1 0
+
+0.500000 1.00000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+1.00000 1.00000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+0.500000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+
+1.00000 0.500000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+
+1.00000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 1.00000 1 0
+0.00000 0.00000 1.00000 1 0
+0.00000 0.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+
+0.00000 0.00000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+
+0.500000 0.00000 0.500000 1 0
+1.00000 0.00000 0.500000 1 0
+1.00000 0.00000 1.00000 1 0
+0.500000 0.00000 1.00000 1 0
+0.500000 0.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+1.00000 0.500000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+
+1.00000 0.00000 1.00000 1 0
+1.00000 0.500000 1.00000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.00000 1.00000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+0.500000 1.00000 1.00000 1 0
+0.00000 1.00000 1.00000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.500000 0.500000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+
+0.00000 0.500000 1.00000 1 0
+0.00000 1.00000 1.00000 1 0
+
+0.500000 0.500000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+1.00000 0.500000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 1.00000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+1.00000 1.00000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+1.00000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+1.00000 0.500000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+
+0.500000 0.500000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+
+0.00000 0.00000 0.00000 2 0
+0.250000 0.00000 0.00000 2 0
+0.250000 0.00000 0.250000 2 0
+0.00000 0.00000 0.250000 2 0
+0.00000 0.00000 0.00000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+0.250000 0.250000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.00000 0.00000 0.00000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.500000 0.00000 0.00000 2 0
+0.500000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+0.500000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+0.250000 0.250000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.00000 0.500000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+0.250000 0.500000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+0.00000 0.500000 0.00000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.00000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+0.500000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.500000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+0.500000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.500000 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.500000 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.500000 2 0
+0.00000 0.00000 0.500000 2 0
+0.00000 0.00000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+
+0.00000 0.00000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.500000 0.00000 0.250000 2 0
+0.500000 0.00000 0.500000 2 0
+0.250000 0.00000 0.500000 2 0
+0.250000 0.00000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+0.500000 0.250000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.500000 2 0
+0.500000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.00000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.500000 2 0
+0.00000 0.500000 0.500000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+0.00000 0.250000 0.500000 2 0
+0.00000 0.500000 0.500000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+0.500000 0.250000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.500000 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.500000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
+0.250000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+DEAL::transformed grid:
+0.500000 0.00000 0.00000 1 0
+1.00000 0.00000 0.00000 1 0
+1.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+1.25000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 0.00000 1 0
+
+0.500000 0.00000 0.00000 1 0
+0.750000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.250000 0.500000 0.00000 1 0
+0.750000 0.500000 0.00000 1 0
+0.750000 0.500000 0.500000 1 0
+0.250000 0.500000 0.500000 1 0
+0.250000 0.500000 0.00000 1 0
+
+1.00000 1.00000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+1.50000 1.00000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+1.00000 1.00000 0.00000 1 0
+
+0.250000 0.500000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+1.25000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 0.00000 1 0
+
+1.50000 1.00000 0.00000 1 0
+2.00000 1.00000 0.00000 1 0
+2.00000 1.00000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+1.50000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+
+1.25000 0.500000 0.00000 1 0
+2.00000 1.00000 0.00000 1 0
+
+1.25000 0.500000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 1.00000 1 0
+0.00000 0.00000 1.00000 1 0
+0.00000 0.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+0.250000 0.500000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.250000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+
+0.00000 0.00000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+
+0.500000 0.00000 0.500000 1 0
+1.00000 0.00000 0.500000 1 0
+1.00000 0.00000 1.00000 1 0
+0.500000 0.00000 1.00000 1 0
+0.500000 0.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+1.25000 0.500000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+
+1.00000 0.00000 1.00000 1 0
+1.25000 0.500000 1.00000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+
+0.250000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+0.250000 0.500000 0.500000 1 0
+
+1.00000 1.00000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+1.50000 1.00000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.750000 0.500000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+
+0.250000 0.500000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+1.25000 0.500000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+0.750000 0.500000 0.500000 1 0
+
+1.50000 1.00000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+2.00000 1.00000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+1.25000 0.500000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+
+1.25000 0.500000 1.00000 1 0
+2.00000 1.00000 1.00000 1 0
+
+0.750000 0.500000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+
+0.00000 0.00000 0.00000 2 0
+0.250000 0.00000 0.00000 2 0
+0.250000 0.00000 0.250000 2 0
+0.00000 0.00000 0.250000 2 0
+0.00000 0.00000 0.00000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+0.312500 0.250000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.00000 0.00000 0.00000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.500000 0.00000 0.00000 2 0
+0.500000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+0.625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+0.312500 0.250000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.250000 0.500000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+0.500000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+0.625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.500000 0.500000 0.00000 2 0
+0.750000 0.500000 0.00000 2 0
+0.750000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.625000 0.250000 0.00000 2 0
+0.750000 0.500000 0.00000 2 0
+
+0.625000 0.250000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.500000 2 0
+0.00000 0.00000 0.500000 2 0
+0.00000 0.00000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.375000 0.250000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+
+0.00000 0.00000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.500000 0.00000 0.250000 2 0
+0.500000 0.00000 0.500000 2 0
+0.250000 0.00000 0.500000 2 0
+0.250000 0.00000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+0.625000 0.250000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.500000 2 0
+0.625000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.375000 0.250000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.375000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
+0.125000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+0.625000 0.250000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.500000 0.500000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+0.750000 0.500000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.625000 0.250000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+
+0.625000 0.250000 0.500000 2 0
+0.750000 0.500000 0.500000 2 0
+
+0.375000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
{
public:
SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format);
+ const DataOutBase::OutputFormat output_format);
virtual void operator () (const hp::DoFHandler<dim> &dof_handler,
const Vector<double> &solution) const;
private:
const std::string output_name_base;
- const typename DataOut<dim>::OutputFormat output_format;
+ const DataOutBase::OutputFormat output_format;
};
template <int dim>
SolutionOutput<dim>::
SolutionOutput (const std::string &output_name_base,
- const typename DataOut<dim>::OutputFormat output_format)
+ const DataOutBase::OutputFormat output_format)
:
output_name_base (output_name_base),
output_format (output_format)
Evaluation::SolutionOutput<dim>
postprocessor2 (std::string("solution-")+solver_name,
- DataOut<dim>::gnuplot);
+ DataOutBase::gnuplot);
std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
postprocessor_list.push_back (&postprocessor1);
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::mmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+ const unsigned int m=2;
+ const unsigned int n=3;
+ const unsigned int k=4;
+ FullMatrix<double> A(m, k), B(k, n), C(m, n), OC(m,n);
+ LAPACKFullMatrix<double> AL(m, k), BL(k, n), CL(m, n);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<k; ++j)
+ A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+ for (unsigned int i=0; i<k; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+ A.mmult(C, B);
+ AL.mmult(CL, BL);
+ AL.mmult(OC, BL);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ {
+ Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+ Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+int main()
+{
+ const std::string logname = "output";
+ std::ofstream logfile(logname.c_str());
+ logfile.precision(3);
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::Tmmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+ const unsigned int m=2;
+ const unsigned int n=3;
+ const unsigned int k=4;
+ FullMatrix<double> A(k, m), B(k, n), C(m, n), OC(m,n);
+ LAPACKFullMatrix<double> AL(k,m), BL(k, n), CL(m, n);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<k; ++j)
+ A(j,i) = AL(j,i) = (double)rand()/RAND_MAX;
+ for (unsigned int i=0; i<k; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+ A.Tmmult(C, B);
+ AL.Tmmult(CL, BL);
+ AL.Tmmult(OC, BL);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ {
+ Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+ Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+int main()
+{
+ const std::string logname = "output";
+ std::ofstream logfile(logname.c_str());
+ logfile.precision(3);
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::mTmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+ const unsigned int m=2;
+ const unsigned int n=3;
+ const unsigned int k=4;
+ FullMatrix<double> A(m, k), B(n, k), C(m, n), OC(m,n);
+ LAPACKFullMatrix<double> AL(m, k), BL(n, k), CL(m, n);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<k; ++j)
+ A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+ for (unsigned int i=0; i<n; ++i)
+ for (unsigned int j=0; j<k; ++j)
+ B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+ A.mTmult(C, B);
+ AL.mTmult(CL, BL);
+ AL.mTmult(OC, BL);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ {
+ Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+ Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+int main()
+{
+ const std::string logname = "output";
+ std::ofstream logfile(logname.c_str());
+ logfile.precision(3);
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::TmTmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+ const unsigned int m=2;
+ const unsigned int n=3;
+ const unsigned int k=4;
+ FullMatrix<double> A(k, m), B(n, k), C(m, n), OC(m,n);
+ LAPACKFullMatrix<double> AL(k, m), BL(n, k), CL(m, n);
+ for (unsigned int i=0; i<k; ++i)
+ for (unsigned int j=0; j<m; ++j)
+ A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+ for (unsigned int i=0; i<n; ++i)
+ for (unsigned int j=0; j<k; ++j)
+ B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+ A.TmTmult(C, B);
+ AL.TmTmult(CL, BL);
+ AL.TmTmult(OC, BL);
+ for (unsigned int i=0; i<m; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ {
+ Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+ Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+int main()
+{
+ const std::string logname = "output";
+ std::ofstream logfile(logname.c_str());
+ logfile.precision(3);
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::apply_lu_factorization in two different variants
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+ const unsigned int n=11;
+ LAPACKFullMatrix<double> A(n,n);
+ for (unsigned int i=0; i<n; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ A(i,j) = (double)rand()/RAND_MAX;
+ A.compute_lu_factorization();
+ LAPACKFullMatrix<double> rhs_orig(n, 3);
+ for (unsigned int i=0; i<3; ++i)
+ for (unsigned int j=0; j<n; ++j)
+ rhs_orig(j,i) = 2.32 * rand() / RAND_MAX - 0.9923;
+
+ for (unsigned int transpose=0; transpose < 2; ++transpose)
+ {
+ LAPACKFullMatrix<double> rhs(rhs_orig);
+ A.apply_lu_factorization(rhs, transpose);
+ for (unsigned int i=0; i<3; ++i)
+ {
+ Vector<double> check(n);
+ for (unsigned int j=0; j<n; ++j)
+ check(j) = rhs_orig(j, i);
+ A.apply_lu_factorization(check, transpose);
+ for (unsigned int j=0; j<n; ++j)
+ Assert(std::abs(check(j) - rhs(j,i)) < 1e-13, ExcInternalError());
+ }
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+int main()
+{
+ const std::string logname = "output";
+ std::ofstream logfile(logname.c_str());
+ logfile.precision(3);
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ test();
+}
--- /dev/null
+
+DEAL::OK
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id: full_matrix_01.cc 31602 2013-11-09 15:38:36Z young $
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// check initialiser (aka do_reinit). .
+//
+// PETScWrappers::FullMatrix::reinit ()
+
+#include "../tests.h"
+#include <deal.II/lac/petsc_full_matrix.h>
+#include <fstream>
+#include <iostream>
+
+// Simply take an already intialised full matrix, fill in some of the
+// elements, reinitialise it to a different size and fill in some
+// elements again. To be sure this generates the correct results the
+// test is verbose (and uses tiny matrices).
+void test (PETScWrappers::FullMatrix &m)
+{
+ // asign some matrix elements
+ for (unsigned int i=0; i<m.m(); ++i)
+ for (unsigned int j=0; j<m.n(); ++j)
+ m.set (i, j, i+2*j);
+
+ m.compress (VectorOperation::add);
+
+ // things we know
+ Assert (m.m() == 3, ExcInternalError());
+ Assert (m.n() == 3, ExcInternalError());
+
+ // Generate some output
+ deallog << "initial matrix: " << std::endl;
+ for (unsigned int i=0; i<m.m(); ++i)
+ {
+ for (unsigned int j=0; j<m.n(); ++j)
+ deallog << m(i,j) << " ";
+ deallog << std::endl;
+ }
+ deallog << std::endl;
+
+ // test reinit, this time a different size matrix
+ m.reinit (5, 5);
+
+ // set some entries
+ for (unsigned int i=0; i<m.m(); ++i)
+ for (unsigned int j=0; j<m.n(); ++j)
+ m.set (i, j, j+2*i);
+ m.compress (VectorOperation::add);
+
+ // things we know
+ Assert (m.m() == 5, ExcInternalError());
+ Assert (m.n() == 5, ExcInternalError());
+
+ // Generate some output
+ deallog << "after reinit: " << std::endl;
+ for (unsigned int i=0; i<m.m(); ++i)
+ {
+ for (unsigned int j=0; j<m.n(); ++j)
+ deallog << m(i,j) << " ";
+ deallog << std::endl;
+ }
+ deallog << std::endl;
+
+ // done
+ deallog << "OK" << std::endl;
+}
+
+int main (int argc,char **argv)
+{
+ std::ofstream logfile("output");
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ try
+ {
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+ {
+ // Standard intialiser...
+ PETScWrappers::FullMatrix m (3,3);
+ test (m);
+ }
+
+ }
+ catch (std::exception &exc)
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Exception on processing: " << std::endl
+ << exc.what() << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+
+ return 1;
+ }
+ catch (...)
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Unknown exception!" << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ };
+}
--- /dev/null
+
+DEAL::initial matrix:
+DEAL::0 2.00000 4.00000
+DEAL::1.00000 3.00000 5.00000
+DEAL::2.00000 4.00000 6.00000
+DEAL::
+DEAL::after reinit:
+DEAL::0 1.00000 2.00000 3.00000 4.00000
+DEAL::2.00000 3.00000 4.00000 5.00000 6.00000
+DEAL::4.00000 5.00000 6.00000 7.00000 8.00000
+DEAL::6.00000 7.00000 8.00000 9.00000 10.0000
+DEAL::8.00000 9.00000 10.0000 11.0000 12.0000
+DEAL::
+DEAL::OK