# Include information about bundled libraries:
#
IF(DEAL_II_HAVE_BUNDLED_DIRECTORY)
- INCLUDE(bundled/CMakeLists.txt)
+ FILE(GLOB _check_files "bundled/*.cmake")
+ LIST(SORT _check_files)
+ FOREACH(_file ${_check_files})
+ MESSAGE(STATUS "")
+ MESSAGE(STATUS "Include ${_file}")
+ INCLUDE(${_file})
+ ENDFOREACH()
ENDIF()
#
## ---------------------------------------------------------------------
#
-# Export information about bundled library locations and do the actual
-# setup of compilation targets and installation here:
+# Compile and install enabled bundled features:
#
+MESSAGE(STATUS "Setup bundled features")
-#
-# Boost C++ libraries
-#
-SET(FEATURE_BOOST_HAVE_BUNDLED TRUE)
-OPTION(DEAL_II_FORCE_BUNDLED_BOOST
- "Always use the bundled boost library instead of an external one."
- OFF)
-SET(BOOST_FOLDER "${CMAKE_SOURCE_DIR}/bundled/boost-1.49.0")
IF(FEATURE_BOOST_BUNDLED_CONFIGURED)
INSTALL(DIRECTORY ${BOOST_FOLDER}/include/boost
COMPONENT library
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_THREADS AND NOT DEAL_II_USE_CXX11)
+ IF(DEAL_II_WITH_THREADS AND NOT DEAL_II_USE_CXX11)
#
# If the C++ compiler doesn't completely support the C++11 standard
# (and consequently we can't use std::thread, std::mutex, etc), then
ENDIF()
-#
-# FunctionParser project:
-#
-SET(FEATURE_FUNCTIONPARSER_HAVE_BUNDLED TRUE)
-OPTION(DEAL_II_FORCE_BUNDLED_FUNCTIONPARSER
- "Always use the bundled functionparser library instead of an external one."
- OFF)
-SET(FUNCTIONPARSER_FOLDER "${CMAKE_SOURCE_DIR}/bundled/functionparser/")
-
IF(FEATURE_FUNCTIONPARSER_BUNDLED_CONFIGURED)
ADD_SUBDIRECTORY(${FUNCTIONPARSER_FOLDER})
ENDIF()
-#
-# Threading Building Blocks library
-#
-IF(NOT CMAKE_SYSTEM_NAME MATCHES "CYGWIN"
- AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
- #
- # Cygwin is unsupported by tbb, Windows due to the way we compile tbb...
- #
- SET(FEATURE_THREADS_HAVE_BUNDLED TRUE)
- OPTION(DEAL_II_FORCE_BUNDLED_THREADS
- "Always use the bundled tbb library instead of an external one."
- OFF)
- SET(TBB_FOLDER "${CMAKE_SOURCE_DIR}/bundled/tbb41_20130401oss")
-ENDIF()
-
-
IF(FEATURE_THREADS_BUNDLED_CONFIGURED)
INSTALL(DIRECTORY ${TBB_FOLDER}/include/tbb
DESTINATION ${DEAL_II_INCLUDE_RELDIR}/deal.II/bundled
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
+
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
"${TBB_FOLDER}/include\n"
)
ENDIF()
-#
-# UMFPACK, AMD and UFCONFIG:
-#
-SET(FEATURE_UMFPACK_HAVE_BUNDLED TRUE)
-SET(UMFPACK_FOLDER "${CMAKE_SOURCE_DIR}/bundled/umfpack")
-OPTION(DEAL_II_FORCE_BUNDLED_UMFPACK
- "Always use the bundled umfpack library instead of an external one."
- OFF)
-
-#
-# Resolve a cache invalidation problem by searching for these flags
-# unconditionally. They're used for compiling the sources in
-# ${UMFPACK_FOLDER}/UMFPACK/Source depending on cached variables.
-#
-ENABLE_IF_SUPPORTED(_dummy "-Wno-sign-compare")
-ENABLE_IF_SUPPORTED(_dummy "-Wno-write-strings")
-
IF(FEATURE_UMFPACK_BUNDLED_CONFIGURED)
ADD_SUBDIRECTORY(${UMFPACK_FOLDER}/UMFPACK/Source)
ADD_SUBDIRECTORY(${UMFPACK_FOLDER}/AMD/Source)
ENDIF()
+
+MESSAGE(STATUS "Setup bundled features - Done")
--- /dev/null
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2013 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Export information about bundled library locations and do the actual
+# setup of compilation targets and installation here:
+#
+
+#
+# Boost C++ libraries
+#
+
+SET(FEATURE_BOOST_HAVE_BUNDLED TRUE)
+
+OPTION(DEAL_II_FORCE_BUNDLED_BOOST
+ "Always use the bundled boost library instead of an external one."
+ OFF)
+
+SET(BOOST_FOLDER "${CMAKE_SOURCE_DIR}/bundled/boost-1.49.0")
+
+#
+# FunctionParser project:
+#
+
+SET(FEATURE_FUNCTIONPARSER_HAVE_BUNDLED TRUE)
+
+OPTION(DEAL_II_FORCE_BUNDLED_FUNCTIONPARSER
+ "Always use the bundled functionparser library instead of an external one."
+ OFF)
+
+SET(FUNCTIONPARSER_FOLDER "${CMAKE_SOURCE_DIR}/bundled/functionparser/")
+
+#
+# Threading Building Blocks library
+#
+
+IF( NOT CMAKE_SYSTEM_NAME MATCHES "CYGWIN"
+ AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ #
+ # Cygwin is unsupported by tbb, Windows due to the way we compile tbb...
+ #
+ SET(FEATURE_THREADS_HAVE_BUNDLED TRUE)
+
+ OPTION(DEAL_II_FORCE_BUNDLED_THREADS
+ "Always use the bundled tbb library instead of an external one."
+ OFF)
+
+ SET(TBB_FOLDER "${CMAKE_SOURCE_DIR}/bundled/tbb41_20130401oss")
+ENDIF()
+
+#
+# UMFPACK, AMD and UFCONFIG:
+#
+
+SET(FEATURE_UMFPACK_HAVE_BUNDLED TRUE)
+
+OPTION(DEAL_II_FORCE_BUNDLED_UMFPACK
+ "Always use the bundled umfpack library instead of an external one."
+ OFF)
+
+SET(UMFPACK_FOLDER "${CMAKE_SOURCE_DIR}/bundled/umfpack")
# two distinct set ups.
#
+MESSAGE(STATUS "Setup project configuration")
+
#
# Read in auxiliary include directories for the build directory
# configuration:
COMPONENT compat_files
)
ENDIF()
+
+MESSAGE(STATUS "Setup project configuration - Done")
MACRO(DEAL_II_INVOKE_AUTOPILOT)
+ # Generator specific values:
+ IF(CMAKE_GENERATOR MATCHES "Ninja")
+ #
+ # Ninja doesn't like a redifinition of the "help" target, so use "info"
+ # in this case...
+ #
+ SET(_make_command "$ ninja")
+ ELSE()
+ SET(_make_command " $ make")
+ ENDIF()
+
# Define and setup a compilation target:
ADD_EXECUTABLE(${TARGET} ${TARGET_SRC})
DEAL_II_SETUP_TARGET(${TARGET})
COMMENT "Run ${TARGET} with ${CMAKE_BUILD_TYPE} configuration"
)
SET(_run_targets
- "# $ make run - to (compile, link and) run the program\n"
+ "# ${_make_command} run - to (compile, link and) run the program\n"
)
ENDIF()
ENDIF()
SET(_run_targets
- "${_run_targets}#\n# $ make sign - to sign the executable with the supplied OSX developer key\n"
+ "${_run_targets}#\n# ${_make_command} sign - to sign the executable with the supplied OSX developer key\n"
)
ENDIF()
# switch between them:
IF(${DEAL_II_BUILD_TYPE} MATCHES "DebugRelease")
SET(_switch_targets
-"# $ make debug - to switch the build type to \"Debug\"
-# $ make release - to switch the build type to \"Release\"\n"
+"# ${_make_command} debug - to switch the build type to 'Debug'
+# ${_make_command} release - to switch the build type to 'Release'\n"
)
ENDIF()
)
ENDIF()
+
# Print out some usage information to file:
FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
"MESSAGE(
\"###
#
-# Successfully set up project ${TARGET} with ${DEAL_II_PACKAGE_NAME}-${DEAL_II_PACKAGE_VERSION} found at
+# Project ${TARGET} set up with ${DEAL_II_PACKAGE_NAME}-${DEAL_II_PACKAGE_VERSION} found at
# ${DEAL_II_PATH}
#
-# CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}
+# CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}
#
# You can now run
-# $ make - to compile and link the program
+# ${_make_command} - to compile and link the program
${_run_targets}#
${_switch_targets}#
-# $ make edit_cache - to change (cached) configuration variables
-# and rerun the configure and generate phases of CMake
-#
-# $ make strip_comments - to strip the source files in this
-# directory off the documentation comments
-# $ make clean - to remove the generated executable as well as
-# all intermediate compilation files
-# $ make runclean - to remove all output generated by the program
-# $ make distclean - to clean the directory from _all_ generated
-# files (includes clean, runclean and the removal
-# of the generated build system)
+")
+ IF(NOT CMAKE_GENERATOR MATCHES "Ninja")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+"# ${_make_command} edit_cache - to change (cached) configuration variables
+# and rerun the configure and generate phases of CMake
#
-# $ make help - to view this message again
+")
+ ENDIF()
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+"# ${_make_command} strip_comments - to strip the source files in this
+# directory off the documentation comments
+# ${_make_command} clean - to remove the generated executable as well as
+# all intermediate compilation files
+# ${_make_command} runclean - to remove all output generated by the program
+# ${_make_command} distclean - to clean the directory from _all_ generated
+# files (includes clean, runclean and the removal
+# of the generated build system)
#
+"
+ )
+ IF(CMAKE_GENERATOR MATCHES "Ninja")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+"# $ ninja info - to view this message again
+"
+ )
+ ELSE()
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+"# $ make help - to view this message again
+" )
+ ENDIF()
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+"#
# Have a nice day!
#
###\")"
- )
+ )
# A custom target to print the message:
- ADD_CUSTOM_TARGET(help
+ ADD_CUSTOM_TARGET(info
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
)
+ IF(NOT CMAKE_GENERATOR MATCHES "Ninja")
+ ADD_CUSTOM_TARGET(help
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake
+ )
+ ENDIF()
# Print this message once:
IF(NOT USAGE_PRINTED)
INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_usage.cmake)
SET(USAGE_PRINTED TRUE CACHE INTERNAL "")
ELSE()
- MESSAGE(STATUS "Run $ make help to print a detailed help message")
+ IF(CMAKE_GENERATOR MATCHES "Ninja")
+ MESSAGE(STATUS "Run $ ninja info to print a detailed help message")
+ ELSE()
+ MESSAGE(STATUS "Run $ make help to print a detailed help message")
+ ENDIF()
ENDIF()
ENDMACRO()
# If TEST_PICKUP_REGEX is set, only tests matching the regex will be
# processed.
#
-# If TEST_OVERRIDE_LOCATION is set, a comparison file category/test.output
-# will be substituted by ${TEST_OVERRIDE_LOCATION}/category/test.output if
-# the latter exists.
-#
# Usage:
# DEAL_II_PICKUP_TESTS()
#
)
IF(DEAL_II_COMPONENT_COMPAT_FILES)
+ MESSAGE(STATUS "Setup compat_files")
#
- # Build and install the old dependency_resolution and report_features
- # executables:
+ # Also build and install the old dependency_resolution executable:
#
- INCLUDE_DIRECTORIES(
- BEFORE # Ensure deal.II include directories come first
- #
- # Reverse order due to BEFORE:
- #
- ${CMAKE_SOURCE_DIR}/include/
- ${CMAKE_BINARY_DIR}/include/
- )
-
ADD_EXECUTABLE(make_dependencies make_dependencies.cc)
- IF(BUILD_SHARED_LIBS)
- SET(_shared_libs "true")
- ELSE()
- SET(_shared_libs "false")
- ENDIF()
- CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/report_features.cc.in
- ${CMAKE_CURRENT_BINARY_DIR}/report_features.cc
- )
-
- ADD_EXECUTABLE(report_features
- ${CMAKE_CURRENT_BINARY_DIR}/report_features.cc
- )
-
- #
- # Link report_features in the same way as the library/final executable:
- #
- TARGET_LINK_LIBRARIES(report_features ${DEAL_II_EXTERNAL_LIBRARIES})
- SET_TARGET_PROPERTIES(report_features
- PROPERTIES
- LINK_FLAGS "${DEAL_II_LINKER_FLAGS}"
- COMPILE_DEFINITIONS "${DEAL_II_DEFINITIONS}"
- )
- IF(DEAL_II_STATIC_EXECUTABLE)
- SET_PROPERTY(TARGET report_features PROPERTY
- LINK_SEARCH_END_STATIC TRUE
- )
- ENDIF()
-
- IF(NOT CMAKE_CROSSCOMPILING)
- ADD_CUSTOM_TARGET(run_report_features COMMAND report_features)
- ENDIF()
-
ADD_DEPENDENCIES(compat_files
expand_instantiations_exe
make_dependencies
- report_features
)
- SET_TARGET_PROPERTIES(expand_instantiations_exe make_dependencies report_features
+ SET_TARGET_PROPERTIES(expand_instantiations_exe make_dependencies
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${DEAL_II_COMMON_RELDIR}/scripts
)
- INSTALL(TARGETS expand_instantiations_exe make_dependencies report_features
+ INSTALL(TARGETS expand_instantiations_exe make_dependencies
DESTINATION ${DEAL_II_COMMON_RELDIR}/scripts
COMPONENT compat_files
)
+ MESSAGE(STATUS "Setup compat_files - Done")
ENDIF()
+++ /dev/null
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 2013 by the deal.II authors
-//
-// This file is part of the deal.II library.
-//
-// The deal.II library is free software; you can use it, redistribute
-// it, and/or modify it under the terms of the GNU Lesser General
-// Public License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// The full text of the license can be found in the file LICENSE at
-// the top level of the deal.II distribution.
-//
-// ---------------------------------------------------------------------
-
-#include <deal.II/base/config.h>
-
-#include <iostream>
-
-#include <boost/version.hpp>
-
-#ifdef DEAL_II_WITH_UMFPACK
-extern "C" {
-#include <umfpack.h>
-}
-#endif
-
-#if defined(DEAL_II_WITH_MPI)
-#include <mpi.h>
-#endif
-
-#ifdef DEAL_II_WITH_TRILINOS
-# include <Trilinos_version.h>
-#endif
-
-#ifdef DEAL_II_WITH_MUMPS
-# include <deal.II/base/utilities.h>
-# include <dmumps_c.h>
-#endif
-
-#ifdef DEAL_II_WITH_PETSC
-# include <petscversion.h>
-#endif
-
-#ifdef DEAL_II_WITH_SLEPC
-# include <slepcversion.h>
-#endif
-
-// Output configuration options from config.h.
-// The format of each line is
-//
-// deal-feature: FEATURE=value
-//
-// no spaces in any token!
-
-int main()
-{
- std::cout << "dealii-feature: target="
- << "@CMAKE_SYSTEM_NAME@" << std::endl;
- std::cout << "dealii-feature: compiler="
- << "@CMAKE_CXX_COMPILER_ID@@CMAKE_CXX_COMPILER_VERSION@"
- << std::endl;
- if(${_shared_libs})
- std::cout << "dealii-feature: shared_libs=yes" << std::endl;
- else
- std::cout << "dealii-feature: shared_libs=no" << std::endl;
-
-#ifdef DEAL_II_WITH_ARPACK
- std::cout << "dealii-feature: ARPACK=yes" << std::endl;
-#endif
-
-std::cout << "dealii-feature: BOOST="
- << BOOST_VERSION / 100000 << "."
- << BOOST_VERSION / 100 % 1000
- << std::endl;
-
-#ifdef DEAL_II_WITH_FUNCTIONPARSER
- std::cout << "dealii-feature: parser=yes" << std::endl;
-#else
- std::cout << "dealii-feature: parser=no" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_HDF5
- std::cout << "dealii-feature: HDF5=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_LAPACK
- std::cout << "dealii-feature: BLAS=yes" << std::endl;
- std::cout << "dealii-feature: LAPACK=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_METIS
- std::cout << "dealii-feature: METIS=yes" << std::endl;
-#endif
-
-#if defined(DEAL_II_WITH_MPI)
-# ifdef OMPI_MAJOR_VERSION
- std::cout << "dealii-feature: MPI=OpenMPI-"
- << OMPI_MAJOR_VERSION << '.'
- << OMPI_MINOR_VERSION << '.'
- << OMPI_RELEASE_VERSION << std::endl;
-# else
- std::cout << "dealii-feature: MPI="
- << MPI_VERSION << '.'
- << MPI_SUBVERSION << std::endl;
-# endif
-#endif
-
-#ifdef DEAL_II_WITH_MUMPS
- std::cout << "dealii-feature: MUMPS=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_P4EST
- std::cout << "dealii-feature: P4est=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_PETSC
- std::cout << "dealii-feature: PETSc="
- << PETSC_VERSION_MAJOR << '.'
- << PETSC_VERSION_MINOR << '.'
- << PETSC_VERSION_SUBMINOR << "-p"
- << PETSC_VERSION_PATCH << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_SLEPC
- std::cout << "dealii-feature: SLEPc="
- << SLEPC_VERSION_MAJOR << '.'
- << SLEPC_VERSION_MINOR << '.'
- << SLEPC_VERSION_SUBMINOR << "-p"
- << SLEPC_VERSION_PATCH << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_NETCDF
- std::cout << "dealii-feature: NetCDF=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_TECPLOT
- std::cout << "dealii-feature: Tecplot=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_THREADS
- std::cout << "dealii-feature: multithreading=yes" << std::endl;
-#else
- std::cout << "dealii-feature: multithreading=no" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_TRILINOS
-# ifdef TRILINOS_VERSION_STRING
- std::cout << "dealii-feature: Trilinos=" << TRILINOS_VERSION_STRING << std::endl;
-# else
- const unsigned int trilinos_subminor = TRILINOS_MAJOR_MINOR_VERSION % 100;
- const unsigned int trilinos_minor = (TRILINOS_MAJOR_MINOR_VERSION/100) % 100;
- std::cout << "dealii-feature: Trilinos="
- << TRILINOS_MAJOR_VERSION << '.'
- << trilinos_minor << '.'
- << trilinos_subminor << std::endl;
-# endif
-#endif
-
-#ifdef DEAL_II_WITH_UMFPACK
- std::cout << "dealii-feature: UMFPACK="
- << UMFPACK_MAIN_VERSION << '.'
- << UMFPACK_SUB_VERSION << '.'
- << UMFPACK_SUBSUB_VERSION << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_ZLIB
- std::cout << "dealii-feature: LibZ=yes" << std::endl;
-#endif
-
-#ifdef DEAL_II_WITH_64BIT_INDICES
- std::cout << "dealii-feature: 64bit_indices=yes" <<std::endl;
-#endif
-}
# TEST_DIFF
# TEST_TIME_LIMIT
# TEST_PICKUP_REGEX
-# TEST_OVERRIDE_LOCATION
#
# For details, consult the ./README file.
#
UNSET(ENV{CXXFLAGS})
UNSET(ENV{LDFLAGS})
+#
+# Also respect DEAL_II_CXX_FLAGS - it just too easy to accientally write
+# DEAL_II_CXX_FLAGS instead of CMAKE_CXX_FLAGS... (this was a poor design
+# choice, I know...)
+#
+IF(NOT "${DEAL_II_CXX_FLAGS}" STREQUAL "")
+ MESSAGE(STATUS
+ "Appending \${DEAL_II_CXX_FLAGS} to saved \${CMAKE_CXX_FLAGS}"
+ )
+ SET(CMAKE_CXX_FLAGS_SAVED "${CMAKE_CXX_FLAGS_SAVED} ${DEAL_II_CXX_FLAGS}")
+ENDIF()
+
+
########################################################################
# #
#
MESSAGE(STATUS "")
-IF(NOT "${CMAKE_CXX_FLAGS_SAVED}" STREQUAL "${DEAL_II_CXX_FLAGS_SAVED}")
+IF(NOT "${CMAKE_CXX_FLAGS_SAVED}" STREQUAL "${CACHED_CMAKE_CXX_FLAGS_SAVED}")
# Rerun this test if cxx flags changed:
UNSET(DEAL_II_HAVE_USABLE_CXX_FLAGS CACHE)
ENDIF()
-SET(DEAL_II_CXX_FLAGS_SAVED "${CMAKE_CXX_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
+SET(CACHED_CMAKE_CXX_FLAGS_SAVED "${CMAKE_CXX_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
# Initialize all CMAKE_REQUIRED_* variables a this point:
RESET_CMAKE_REQUIRED()
MESSAGE(FATAL_ERROR "\n"
"Configuration error: Cannot compile with the user supplied CXX flags:\n"
"${CMAKE_CXX_FLAGS_SAVED}\n"
+ "Please check the CMake variable CMAKE_CXX_FLAGS and the\n"
+ "environment variable CXXFLAGS\n\n"
)
ENDIF()
# parameter_gui
#
-# The library can always be installed ;-)
-ADD_CUSTOM_TARGET(library
- COMMAND ${CMAKE_COMMAND}
- -DCOMPONENT="library" -P cmake_install.cmake
- COMMENT "Build and install component \"library\"."
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
- )
-FOREACH(_component compat_files documentation examples mesh_converter parameter_gui)
- STRING(TOUPPER "${_component}" _component_uppercase)
- IF(DEAL_II_COMPONENT_${_component_uppercase})
- ADD_CUSTOM_TARGET(${_component}
+IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
+ #
+ # In case that CMAKE_INSTALL_PREFIX wasn't set, we assume that the user
+ # doesn't actually want to install but just use deal.II in the build
+ # directory. In this case, do not add the "install" phase to the
+ # convenience targets.
+ #
+ MACRO(_add_custom_target _name)
+ ADD_CUSTOM_TARGET(${_name})
+ ENDMACRO()
+
+ # Print precise informations about the convenience targets:
+ SET(_description_string "build")
+ELSE()
+ MACRO(_add_custom_target _name)
+ ADD_CUSTOM_TARGET(${_name}
COMMAND ${CMAKE_COMMAND}
- -DCOMPONENT="${_component}" -P cmake_install.cmake
- COMMENT "Build and install component \"${_component}\"."
+ -DCOMPONENT="${_name}" -P cmake_install.cmake
+ COMMENT "Build and install component \"library\"."
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
+ ENDMACRO()
+
+ # Print precise informations about the convenience targets:
+ SET(_description_string "build and install")
+ENDIF()
+
+# The library can always be compiled and/or installed unconditionally ;-)
+_add_custom_target(library)
+
+FOREACH(_component compat_files documentation examples mesh_converter parameter_gui)
+ STRING(TOUPPER "${_component}" _component_uppercase)
+ IF(DEAL_II_COMPONENT_${_component_uppercase})
+ _add_custom_target(${_component})
ELSE()
STRING(TOUPPER ${_component} _componentuppercase)
ADD_CUSTOM_TARGET(${_component}
${CMAKE_COMMAND} -E echo ''
&& ${CMAKE_COMMAND} -E echo ''
&& ${CMAKE_COMMAND} -E echo '***************************************************************************'
- && ${CMAKE_COMMAND} -E echo "** Error: Could not build and install disabled component \"${_component}\"."
+ && ${CMAKE_COMMAND} -E echo "** Error: Could not ${_description_string} disabled component \"${_component}\"."
&& ${CMAKE_COMMAND} -E echo "** Please reconfigure with -DDEAL_II_COMPONENT_${_componentuppercase}=ON"
&& ${CMAKE_COMMAND} -E echo '***************************************************************************'
&& ${CMAKE_COMMAND} -E echo ''
# Provide an "info" target to print a help message:
#
+IF(CMAKE_GENERATOR MATCHES "Ninja")
+ SET(_make_command "ninja")
+ELSE()
+ SET(_make_command "make")
+ENDIF()
FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
"MESSAGE(
\"###
#
-# The following targets are available (invoke by $ make <target>):
+# The following targets are available (invoke by $ ${_make_command} <target>):
#
-# all - compiles the library and all enabled components
-# clean - removes all generated files
-# install - installs into CMAKE_INSTALL_PREFIX
-# help - prints a list of valid top level targets
-# info - prints this help message
+# all - compile the library and all enabled components
+# clean - remove all generated files
+# install - install into CMAKE_INSTALL_PREFIX
+")
+
+IF(CMAKE_GENERATOR MATCHES "Ninja")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
+"# info - print this help message
+# help - print a list of valid top level targets
+#
+")
+ELSE()
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
+"# help - print this help message in the toplevel directory,
+# otherwise print a list of targets (in subdirectories)
#
-# edit_cache - runs ccmake for changing (cached) configuration variables
+")
+ENDIF()
+
+FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
+"# edit_cache - run ccmake for changing (cached) configuration variables
# and reruns the configure and generate phases of CMake
-# rebuild_cache - reruns the configure and generate phases of CMake
+# rebuild_cache - rerun the configure and generate phases of CMake
#
-# compat_files - builds and installs the 'compat_files' component
-# documentation - builds and installs the 'documentation' component
-# examples - builds and installs the 'examples' component
-# library - builds and installs the 'library' component
-# mesh_converter - builds and installs the 'mesh_converter' component
-# parameter_gui - builds and installs the 'parameter_gui' component
+# compat_files - ${_description_string} component 'compat_files'
+# documentation - ${_description_string} component 'documentation'
+# examples - ${_description_string} component 'examples'
+# library - ${_description_string} component 'library'
+# mesh_converter - ${_description_string} component 'mesh_converter'
+# parameter_gui - ${_description_string} component 'parameter_gui'
#
-# test - runs a minimal set of tests
+# test - run a minimal set of tests
#
-# setup_tests - sets up the testsuite subprojects
+# setup_tests - set up the testsuite subprojects
# regen_tests - rerun configure stage in every testsuite subprojects
-# clean_tests - runs the 'clean' target in every testsuite subproject
-# prune_tests - removes all testsuite subprojects
+# clean_tests - run the 'clean' target in every testsuite subproject
+# prune_tests - remove all testsuite subprojects
#
###\")"
)
+
ADD_CUSTOM_TARGET(info
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
)
+IF(NOT CMAKE_GENERATOR MATCHES "Ninja")
+ ADD_CUSTOM_TARGET(help
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
+ )
+ENDIF()
_summary(
"#\n# Detailed information (compiler flags, feature configuration) can be found in detailed.log
-#\n# Run $ make info to print a help message with a list of top level targets\n"
+#\n# Run $ "
)
+IF(CMAKE_GENERATOR MATCHES "Ninja")
+ _summary("ninja info")
+ELSE()
+_summary("make help")
+ENDIF()
+_summary(" to print a help message with a list of top level targets\n")
_both("#\n###")
# environment or command line:
#
# TEST_DIFF
-# TEST_OVERRIDE_LOCATION
# TEST_PICKUP_REGEX
# TEST_TIME_LIMIT
#
TEST_DIFF
TEST_TIME_LIMIT
TEST_PICKUP_REGEX
- TEST_OVERRIDE_LOCATION
)
# Environment wins:
IF(DEFINED ENV{${_var}})
SET(${_var} $ENV{${_var}})
ENDIF()
IF(NOT "${_var}" STREQUAL "")
- SET(${_var} "${${_var}}" CACHE STRING "")
+ SET(${_var} "${${_var}}" CACHE STRING "" FORCE)
ENDIF()
ENDFOREACH()
LIST(APPEND _options -DDEAL_II_SOURCE_DIR=${CMAKE_SOURCE_DIR})
LIST(APPEND _options -DDEAL_II_BINARY_DIR=${CMAKE_BINARY_DIR})
FOREACH(_var
- DIFF_DIR NUMDIFF_DIR TEST_DIFF TEST_OVERRIDE_LOCATION TEST_PICKUP_REGEX
- TEST_TIME_LIMIT
+ DIFF_DIR NUMDIFF_DIR TEST_DIFF TEST_PICKUP_REGEX TEST_TIME_LIMIT
)
# always undefine:
LIST(APPEND _options "-U${_var}")
## ---------------------------------------------------------------------
IF(DEAL_II_COMPONENT_MESH_CONVERTER)
+ MESSAGE(STATUS "Setup mesh_converter")
ADD_SUBDIRECTORY(mesh_conversion)
+ MESSAGE(STATUS "Setup mesh_converter - Done")
ENDIF()
IF(DEAL_II_COMPONENT_PARAMETER_GUI)
+ MESSAGE(STATUS "Setup parameter_gui")
ADD_SUBDIRECTORY(parameter_gui)
+ MESSAGE(STATUS "Setup parameter_gui - Done")
ENDIF()
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#PROJECT(mesh_converter)
+IF("${DEAL_II_EXECUTABLE_RELDIR}" STREQUAL "")
+ SET(DEAL_II_EXECUTABLE_RELDIR "bin")
+ENDIF()
+
ADD_EXECUTABLE(mesh_converter_exe
Main.cc
MeshConversion.cc
)
SET_TARGET_PROPERTIES(mesh_converter_exe
- PROPERTIES OUTPUT_NAME mesh_converter
+ PROPERTIES
+ OUTPUT_NAME mesh_converter
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${DEAL_II_EXECUTABLE_RELDIR}"
)
ADD_DEPENDENCIES(mesh_converter mesh_converter_exe)
-IF("${DEAL_II_EXECUTABLE_RELDIR}" STREQUAL "")
- SET(DEAL_II_EXECUTABLE_RELDIR "bin")
-ENDIF()
-
INSTALL(TARGETS mesh_converter_exe
RUNTIME DESTINATION ${DEAL_II_EXECUTABLE_RELDIR}
COMPONENT mesh_converter
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#PROJECT(parameter_gui)
+IF("${DEAL_II_EXECUTABLE_RELDIR}" STREQUAL "")
+ SET(DEAL_II_EXECUTABLE_RELDIR "bin")
+ENDIF()
+
FIND_PACKAGE(Qt4 REQUIRED QtCore QtGui QtXml)
MARK_AS_ADVANCED(QT_QMAKE_EXECUTABLE)
${SOURCE_MOC}
${SOURCE_RCC}
)
-SET_TARGET_PROPERTIES(parameter_gui_exe PROPERTIES OUTPUT_NAME parameter_gui)
+SET_TARGET_PROPERTIES(parameter_gui_exe
+ PROPERTIES
+ OUTPUT_NAME parameter_gui
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${DEAL_II_EXECUTABLE_RELDIR}"
+ )
TARGET_LINK_LIBRARIES(parameter_gui_exe ${QT_LIBRARIES})
ADD_DEPENDENCIES(parameter_gui parameter_gui_exe)
-IF("${DEAL_II_EXECUTABLE_RELDIR}" STREQUAL "")
- SET(DEAL_II_EXECUTABLE_RELDIR "bin")
-ENDIF()
-
INSTALL(TARGETS parameter_gui_exe
RUNTIME DESTINATION ${DEAL_II_EXECUTABLE_RELDIR}
COMPONENT parameter_gui
)
EXPORT(TARGETS parameter_gui_exe
- FILE ${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
+ FILE
+ ${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
APPEND
)
-
+++ /dev/null
-#!/usr/bin/make -f
-## ---------------------------------------------------------------------
-## $Id$
-##
-## Copyright (C) 2012 - 2013 by the deal.II authors
-##
-## This file is part of the deal.II library.
-##
-## The deal.II library is free software; you can use it, redistribute
-## it, and/or modify it under the terms of the GNU Lesser General
-## Public License as published by the Free Software Foundation; either
-## version 2.1 of the License, or (at your option) any later version.
-## The full text of the license can be found in the file LICENSE at
-## the top level of the deal.II distribution.
-##
-## ---------------------------------------------------------------------
-
-#
-# A build_test for deal.II
-#
-# Usage: Invoke this script either in a source directory or with $SOURCEDIR
-# set
-#
-# The following environment variables may be set:
-#
-# SOURCEDIR - the source directory to use (if not invoked in a source
-# directory)
-# CONFIGFILE - A cmake configuration file for the build test
-# LOGDIR - directory for the log file
-# LOGFILE - the logfile to use, defaults to
-# $LOGDIR/$CONFIGFILE.<unix time>.log
-#
-# CMAKE - the cmake executable to use
-# SVN - svn info command to use
-# TMPDIR - defaults to "/tmp"
-# CLEAN_TMPDIR - defaults to "true"
-# RUN_EXAMPLES - defaults to "true"
-#
-
-#
-# Specify default values:
-#
-SOURCEDIR=$(CURDIR)
-LOGDIR=$(PWD)
-TMPDIR?=/tmp
-CMAKE=cmake
-SVN=svn info $(SOURCEDIR)
-
-branch:=$(shell $(SVN) | perl -ne 'print "$$1" if m/svn\.dealii\.org.*\/(.+?)\/deal.II/;')
-revision:=$(shell $(SVN) | perl -ne 'print "$$_" if s/Last Changed Rev: //;')
-
-date:= $(shell date +%s)
-random:=$(shell echo "$$RANDOM")
-testdir:= "$(TMPDIR)"/deal-build-test.$(date)-$(random)
-builddir:= $(testdir)/build
-installdir:= $(testdir)/install
-LOGFILE=$(LOGDIR)/$(firstword $(branch) unknown_branch).$(firstword $(notdir $(CONFIGFILE)) no_configuration).$(date).log
-CLEAN_TMPDIR=true
-RUN_EXAMPLES=true
-
-PIPEnTRAP:= >>$(LOGFILE) 2>&1 || (if ${CLEAN_TMPDIR}; then rm -rf $(testdir); fi; false)
-
-.PHONY: main
-main:
- @if test ! -f $(SOURCEDIR)/CMakeLists.txt; then echo "ERROR: $(SOURCEDIR) doesn't seem to be a top-level source directory"; false; fi
- mkdir -p $(LOGDIR)
- mkdir -p $(builddir)
- mkdir -p $(installdir)
- @echo "AUTOMATED DEAL.II BUILD TEST" | tee $(LOGFILE)
- @echo "BEGIN HEADER `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "dealii-feature: branch=$(branch)" | tee -a $(LOGFILE)
- @echo "dealii-feature: revision=$(revision)" | tee -a $(LOGFILE)
- @echo "dealii-feature: user=$(USER)" | tee -a $(LOGFILE)
- @echo "dealii-feature: host=`hostname`" | tee -a $(LOGFILE)
- @echo "dealii-feature: configuration=`basename \"$(CONFIGFILE)\"`" | tee -a $(LOGFILE)
- @echo END HEADER `date -u '+%Y-%m-%d %T'`\n | tee -a $(LOGFILE)
- @echo "BEGIN CONFIGURE OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- cd $(builddir) && $(CMAKE) -C "$(CONFIGFILE)" -DCMAKE_INSTALL_PREFIX=$(installdir) $(SOURCEDIR) $(PIPEnTRAP)
- @echo "END CONFIGURE OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "BEGIN REPORT FEATURES `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- cd $(builddir) && make $(MAKEOPTS) run_report_features $(PIPEnTRAP)
- @echo "END REPORT FEATURES `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "BEGIN BUILD INSTALL OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- cd $(builddir) && make $(MAKEOPTS) install $(PIPEnTRAP)
- @echo "END BUILD INSTALL OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "BEGIN BUILD EXAMPLES OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- cd $(installdir)/examples && make -f $(SOURCEDIR)/contrib/utilities/build_test DEAL_II_DIR=$(installdir) build_examples $(PIPEnTRAP)
- @echo "END BUILD EXAMPLES OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "BEGIN RUN EXAMPLES OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- cd $(installdir)/examples && make -f $(SOURCEDIR)/contrib/utilities/build_test run_examples $(PIPEnTRAP)
- @echo "END RUN EXAMPLES OUTPUT `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- @echo "BUILD TEST SUCCESSFUL `date -u '+%Y-%m-%d %T'`" | tee -a $(LOGFILE)
- if ${CLEAN_TMPDIR}; then rm -rf $(testdir); fi
-
-
-#
-# Recipes used for testing the example steps
-#
-
-steps:= $(wildcard step-*)
-
-%/%:
- -cd $(@D) && $(CMAKE) . >/dev/null 2>&1
- cd $(@D) && if [ -f Makefile ]; then make; fi
-
-.PHONY: build_examples
-build_examples: $(steps:%=%/%)
-
-
-# Run a minimalistic set of steps in debug configuration:
-runsteps_debug:= step-1 step-2 step-3 step-4 step-5 step-6 step-47
-
-# Run all configuration independent steps in release configuration:
-runsteps_release= step-1 step-2 step-3 step-4 step-5 step-6 step-7 step-8 step-9 step-10 step-11 step-12 step-13 step-14 step-16 step-20 step-23 step-25 step-26 step-27 step-28 step-30 step-38 step-39 step-44 step-45 step-47 step-48 step-49
-# step-15 step-21 step-24
-
-
-%/OK_DEBUG:
- cd $(@D) && $(CMAKE) -DCMAKE_BUILD_TYPE=Debug . >/dev/null 2>&1
- cd $(@D) && if $(RUN_EXAMPLES); then make run; fi && touch OK_DEBUG
-
-%/OK_RELEASE:
- cd $(@D) && $(CMAKE) -DCMAKE_BUILD_TYPE=Release . >/dev/null 2>&1
- cd $(@D) && if $(RUN_EXAMPLES); then make run; fi && touch OK_RELEASE
-
-.PHONY: run_examples
-run_examples: $(runsteps_debug:%=%/OK_DEBUG) $(runsteps_release:%=%/OK_RELEASE)
-
##
## ---------------------------------------------------------------------
-
-
-
#
# Set up all necessary bits for the documentation
#
IF(DEAL_II_COMPONENT_DOCUMENTATION)
+ MESSAGE(STATUS "Setup documentation")
+
#
# Required packages for the document generation:
#
# Generate the source documentation via doxygen:
#
ADD_SUBDIRECTORY(doxygen)
-
- #
- # A custom target with the same name as the component:
- #
ADD_DEPENDENCIES(documentation doxygen)
#
COMPONENT documentation
)
+ MESSAGE(STATUS "Setup documentation - Done")
+
ENDIF(DEAL_II_COMPONENT_DOCUMENTATION)
#
installation instructions</a></li>
<li><a href="users/cmake.html" target="body">CMake documentation</a></li>
<li><a href="users/cmakelists.html" target="body">CMake in user projects</a></li>
- <li><a href="doxygen/tutorial/index.html" target="_top">Tutorial</a></li>
+ <li><a href="doxygen/deal.II/Tutorial.html" target="_top">Tutorial</a></li>
<li><a href="doxygen/deal.II/index.html" target="_top">Manual</a></li>
<li><a href="http://www.math.tamu.edu/~bangerth/videos.html" target="_top">Wolfgang's lectures</a></li>
<li><a href="reports/index.html" target="body">Technical reports</a></li>
)
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_header.pl
+ ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_header.pl.in
${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_header.pl
)
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_footer.pl
+ ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_footer.pl.in
${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_footer.pl
)
${CMAKE_SOURCE_DIR}/contrib/parameter_gui/main.cpp
${CMAKE_SOURCE_DIR}/doc/news/*.h
${CMAKE_SOURCE_DIR}/include/deal.II/**/*.h
-
+ )
+LIST(APPEND _doxygen_input
${CMAKE_BINARY_DIR}/include/deal.II/base/config.h
+ ${CMAKE_CURRENT_BINARY_DIR}/tutorial/tutorial.h
)
FOREACH(_step ${DEAL_II_STEPS})
GET_FILENAME_COMPONENT(_step "${_step}" NAME)
DEPENDS ${CMAKE_BINARY_DIR}/doxygen.log
)
-
INSTALL(FILES
${CMAKE_CURRENT_BINARY_DIR}/deal.tag
${CMAKE_CURRENT_SOURCE_DIR}/stylesheet.css
<pre>
Vector &
operator += (Vector &lhs,
- const Vector &rhs) {
+ const Vector &rhs)
{
for (unsigned int i=0; i<lhs.size(); ++i)
lhs(i) += rhs(i);
<pre>
Vector &
operator += (Vector &lhs,
- const Vector &rhs) {
+ const Vector &rhs)
{
Assert (lhs.size() == rhs.size(),
ExcDimensionMismatch (lhs.size(), rhs.size());
follows:
<code>
<pre>
- double norm (const Vector &v) {
+ double norm (const Vector &v)
{
double s = 0;
for (unsigned int i=0; i<v.size(); ++i)
* @mainpage
*
* This is the main starting page for the deal.II class and function
- * documentation. Documentation on other aspects, such as the build system,
- * can be found elsewhere. In addition, there are <a
- * href="../tutorial/index.html">tutorial programs on the use of this
- * library</a>.
+ * documentation. Documentation on other aspects, such as the build
+ * system, can be found elsewhere. In addition, there are
+ * <a href="Tutorial.html">Tutorial programs on the use of the library</a>.
*
* Many of the classes in the deal.II library can be grouped into modules (see
* the <a href="modules.html">Modules page</a> or the corresponding entry in
+++ /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.
-//
-// ---------------------------------------------------------------------
-
-
-/**
- * @page Tutorial Tutorial programs
- *
- * The tutorial is a separate part of the documentation for deal.II. It
- * consists of a collection of small programs, each more or less built atop
- * previous ones. They demonstrate various aspects of the library. A more
- * detailed overview can be found <a href="../tutorial/index.html">on this
- * page</a> that also includes short summaries of what each of the tutorial
- * programs are supposed to demonstrate, as well as a list of the programs
- * sorted by topic.
- */
+++ /dev/null
-## ---------------------------------------------------------------------
-## $Id$
-##
-## Copyright (C) 2006 - 2013 by the deal.II authors
-##
-## This file is part of the deal.II library.
-##
-## The deal.II library is free software; you can use it, redistribute
-## it, and/or modify it under the terms of the GNU Lesser General
-## Public License as published by the Free Software Foundation; either
-## version 2.1 of the License, or (at your option) any later version.
-## The full text of the license can be found in the file LICENSE at
-## the top level of the deal.II distribution.
-##
-## ---------------------------------------------------------------------
-
-$/ = undef;
-
-# Read source for web page
-open TOC, "<toc.html.in";
-$toc = <TOC>;
-close TOC;
-
-# Read generated map file
-open MAP, "<steps.cmapx";
-$map = <MAP>;
-close MAP;
-
-# Insert contents of map file for @@MAP@@
-$toc =~ s/\@\@MAP\@\@/$map/;
-
-print $toc;
my $host = hostname;
my $hosting = << 'EOT'
- Hosting provided by
+ Hosting provided by
<a href="http://www.iwr.uni-heidelberg.de/"><img src="http://www.dealii.org/pictures/IWRlogo4.png" alt="IWR"></a>
<a href="http://www.uni-heidelberg.de/"><img src="http://www.dealii.org/pictures/UniLogo4.png" alt="Universität Heidelberg"></a>
EOT
use strict;
+my $tutorial_file = shift;
+open TUTORIAL, "<$tutorial_file";
+
+# Print the first part of tutorial.h.in
+while (my $line = <TUTORIAL>)
+{
+ last if($line =~ m/\@\@MAP\@\@/);
+ print $line;
+}
+
# List of additional node attributes to highlight purpose and state of the example
my %style = (
"basic" => ',height=.8,width=.8,shape="octagon",fillcolor="green"',
"unfinished" => ',height=.25,width=.25,style="dashed"'
);
-
# Print a preamble setting common attributes
-
print << 'EOT'
digraph StepsMap
{
close TF;
chop $tooltip;
- printf "Step$number [label=\"$number\", URL=\"../deal.II/step_$number.html\", tooltip=\"$tooltip\"";
+ printf "Step$number [label=\"$number\", URL=\"\\ref step_$number\", tooltip=\"$tooltip\"";
# read first line of 'kind' file
print "}\n";
+# Print the rest of tutorial.h.in
+while (my $line = <TUTORIAL>)
+{
+ print $line;
+}
+close TUTORIAL;
background-color: #0000ff;
color: #80ff00;
}
+
+table.tutorial {
+ color: black;
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+div.tutorial {
+ color: black;
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 50px;
+ font-size: 95%;
+}
#
-# Prepare steps.png and steps.cmapx:
+# Prepare tutorial.h:
#
+
ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
COMMAND ${PERL_EXECUTABLE}
ARGS
${CMAKE_SOURCE_DIR}/doc/doxygen/scripts/steps.pl
+ ${CMAKE_CURRENT_SOURCE_DIR}/tutorial.h.in
${DEAL_II_STEPS}
- > ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
- )
-ADD_CUSTOM_COMMAND(
- OUTPUT
- ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- COMMAND ${DOXYGEN_DOT_EXECUTABLE}
- ARGS
- -Tpng -o ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- -Tcmapx -o ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ > ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ ${DEAL_II_STEPS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/tutorial.h.in
)
-
-#
-# Prepare toc.html:
-#
-CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/toc.html.in
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html.in
- COPYONLY
- )
-ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- COMMAND ${PERL_EXECUTABLE}
- ARGS
- ${CMAKE_SOURCE_DIR}/doc/doxygen/scripts/make_toc.pl
- > ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- WORKING_DIRECTORY
- ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html.in
- ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- )
-
-
-#
-# TODO:
-# Are toc-list.html and toc-topics.html really generated by hand?
-#
-
-
#
# A target for the preparation of all the stuff happening in here...
#
+
ADD_CUSTOM_TARGET(tutorial
- DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
)
#
# Prepare the steps for documentation generation
#
+
FOREACH(_step ${DEAL_II_STEPS})
GET_FILENAME_COMPONENT(_step "${_step}" NAME)
)
ADD_DEPENDENCIES(tutorial tutorial_${_step})
ENDFOREACH()
-
-#
-# Install all bits:
-#
-
-INSTALL(FILES
- index.html
- navbar.html
- title.html
- toc-list.html
- toc-topics.html
- ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- DESTINATION ${DEAL_II_DOCHTML_RELDIR}/doxygen/tutorial
- COMPONENT documentation
- )
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN"
- "http://www.w3.org/TR/REC-html40/frameset.dtd">
-<html>
-<head>
-
-<title>Step-by-Step Examples</title>
- <link href="../../screen.css" rel="StyleSheet" type="text/css">
- <meta name="copyright" content="Copyright (C) 1998 - 2013 by the deal.II Authors">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-
-<frameset cols="120,*">
- <frame name="navbar" src="navbar.html" frameborder="0">
- <frame name="body" src="toc.html" frameborder="0">
-</frameset>
-
-<noframes>
-<h1>The deal.II Tutorial</h1>
-Your browser does not seem to understand frames. A version of this
-tutorial that does not use frames can be found
-<a href="toc.html">here</a>.
-</noframes>
-
-</html>
-
-
-
-
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Step-by-Step Examples</title>
- <link href="../../screen.css" rel="StyleSheet" type="text/css">
- <meta name="copyright" content="Copyright (C) 1998 - 2013 by the deal.II Authors">
- <meta name="date" content="$Date$">
- <meta name="svn_id" content="$Id$">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-<body style="background-image:url(../../pictures/deal.II-text.jpg);" lang="en">
-
-
- <p>
- <a href="toc.html" target="body">Overview</a>
- </p>
- <p>
- <a href="toc.html#graph" target="body">Connections between programs</a>
- </p>
- <p>
- <a href="toc-list.html" target="body">Programs by number</a>
- </p>
- <p>
- <a href="toc-topics.html" target="body">Programs by topic</a>
- </p>
-
- <hr>
-
- <p>
- <small><i>Programs by number:</i></small>
- </p>
-
- <p align="center">
- <a href="../../doxygen/deal.II/step_1.html" target="body">1</a>
- <a href="../../doxygen/deal.II/step_2.html" target="body">2</a>
- <a href="../../doxygen/deal.II/step_3.html" target="body">3</a><br />
-
- <a href="../../doxygen/deal.II/step_4.html" target="body">4</a>
- <a href="../../doxygen/deal.II/step_5.html" target="body">5</a>
- <a href="../../doxygen/deal.II/step_6.html" target="body">6</a><br />
-
- <a href="../../doxygen/deal.II/step_7.html" target="body">7</a>
- <a href="../../doxygen/deal.II/step_8.html" target="body">8</a>
- <a href="../../doxygen/deal.II/step_9.html" target="body">9</a><br />
-
- <a href="../../doxygen/deal.II/step_10.html" target="body">10</a>
- <a href="../../doxygen/deal.II/step_11.html" target="body">11</a>
- <a href="../../doxygen/deal.II/step_12.html" target="body">12</a><br />
-
- <a href="../../doxygen/deal.II/step_13.html" target="body">13</a>
- <a href="../../doxygen/deal.II/step_14.html" target="body">14</a>
- <a href="../../doxygen/deal.II/step_15.html" target="body">15</a><br />
-
- <a href="../../doxygen/deal.II/step_16.html" target="body">16</a>
- <a href="../../doxygen/deal.II/step_17.html" target="body">17</a>
- <a href="../../doxygen/deal.II/step_18.html" target="body">18</a><br />
-
- <a href="../../doxygen/deal.II/step_19.html" target="body">19</a>
- <a href="../../doxygen/deal.II/step_20.html" target="body">20</a>
- <a href="../../doxygen/deal.II/step_21.html" target="body">21</a><br />
-
- <a href="../../doxygen/deal.II/step_22.html" target="body">22</a>
- <a href="../../doxygen/deal.II/step_23.html" target="body">23</a>
- <a href="../../doxygen/deal.II/step_24.html" target="body">24</a><br />
-
- <a href="../../doxygen/deal.II/step_25.html" target="body">25</a>
- <a href="../../doxygen/deal.II/step_27.html" target="body">27</a>
- <a href="../../doxygen/deal.II/step_28.html" target="body">28</a><br />
-
- <a href="../../doxygen/deal.II/step_29.html" target="body">29</a>
- <a href="../../doxygen/deal.II/step_30.html" target="body">30</a>
- <a href="../../doxygen/deal.II/step_31.html" target="body">31</a><br />
-
- <a href="../../doxygen/deal.II/step_32.html" target="body">32</a>
- <a href="../../doxygen/deal.II/step_33.html" target="body">33</a>
- <a href="../../doxygen/deal.II/step_34.html" target="body">34</a><br />
-
- <a href="../../doxygen/deal.II/step_35.html" target="body">35</a>
- <a href="../../doxygen/deal.II/step_36.html" target="body">36</a>
- <a href="../../doxygen/deal.II/step_37.html" target="body">37</a><br />
-
- <a href="../../doxygen/deal.II/step_38.html" target="body">38</a>
- <a href="../../doxygen/deal.II/step_39.html" target="body">39</a>
- <a href="../../doxygen/deal.II/step_40.html" target="body">40</a><br />
-
- <a href="../../doxygen/deal.II/step_41.html" target="body">41</a>
- <a href="../../doxygen/deal.II/step_42.html" target="body">42</a>
- <a href="../../doxygen/deal.II/step_43.html" target="body">43</a><br />
-
- <a href="../../doxygen/deal.II/step_44.html" target="body">44</a>
- <a href="../../doxygen/deal.II/step_45.html" target="body">45</a>
- <a href="../../doxygen/deal.II/step_46.html" target="body">46</a><br />
-
- <a href="../../doxygen/deal.II/step_48.html" target="body">48</a>
- <a href="../../doxygen/deal.II/step_49.html" target="body">49</a>
- <a href="../../doxygen/deal.II/step_51.html" target="body">51</a>
- </p>
-
- <hr>
-
- <p>
- <a href="../../index.html" target="_top">Back to the deal.II homepage</a>
- </p>
-
-
- <hr>
-
- <p>
- <a href="../../mail.html" target="body">Comments on the tutorial</a>
- </p>
-
-<!-- Last modified: $Date$ -->
-
-</body>
-</html>
-
-
-
-
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN"
- "http://www.w3.org/TR/REC-html40/frameset.dtd">
-<html>
-<head>
-<title>Step-by-Step Examples</title>
- <link href="../../screen.css" rel="StyleSheet" type="text/css">
- <link rel="SHORTCUT ICON" href="deal.ico">
- <meta name="copyright" content="Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 by the deal.II Authors">
- <meta name="date" content="$Date$">
- <meta name="svn_id" content="$Id$">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-
-
-<body class="title">
- <div class="fixedhead">
- <h1 class="head"> The deal.II tutorial - Step-by-step examples</h1>
- </div>
-</body>
-</html>
-
-
-
-
-
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Step-by-Step</title>
- <meta name="copyright" content="Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by the deal.II Authors">
- <meta name="date" content="$Date$">
- <meta name="svn_id" content="$Id$">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-
-<!-- Page Body -->
-<body lang="en">
-
-<h3>Tutorial programs listed by number</h3>
-
-<table align="center" width="90%">
- <tr valign="top">
- <td width="10%"><a href="../../doxygen/deal.II/step_1.html">Step-1</a></td>
- <td> Creating a grid. A simple way to write it to a file.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_2.html">Step-2</a></td>
- <td> Associate degrees of freedom to
- each vertex and compute the resulting sparsity pattern of
- matrices. Show that renumbering reduces the bandwidth of
- matrices significantly, i.e. clusters nonzero entries around the
- diagonal.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_3.html">Step-3</a></td>
- <td> Actually solve Laplace's
- problem. Object-orientation. Assembling matrices and
- vectors. Boundary values.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_4.html">Step-4</a></td>
- <td> This example is programmed in a
- way that it is independent of the dimension for which we want to
- solve Laplace's equation; we will solve the equation in 2D and
- 3D, although the program is exactly the same. Non-constant right
- hand side function. Non-homogeneous boundary values.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_5.html">Step-5</a></td>
- <td> Computations on successively
- refined grids. Reading a grid from disk. Some optimizations.
- Using assertions. Non-constant coefficient in
- the elliptic operator (yielding the extended Poisson
- equation). Preconditioning the CG solver for the
- linear system of equations.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_6.html">Step-6</a></td>
- <td> Adaptive local
- refinement. Handling of hanging nodes. Higher order elements.
- Catching exceptions in the “main” function.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_7.html">Step-7</a></td>
- <td> Helmholtz
- equation. Non-homogeneous Neumann boundary conditions and
- boundary integrals. Verification of correctness of computed
- solutions. Computing the error between exact and numerical
- solution and output of the data in tables. Using counted pointers.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_8.html">Step-8</a></td>
- <td> The elasticity equations will be
- solved instead of Laplace's equation. The solution is
- vector-valued and the equations form a system with as many
- equations as the dimension of the space in which it is posed.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_9.html">Step-9</a></td>
- <td> Linear advection equation, assembling
- the system of equations in parallel using multi-threading,
- implementing a refinement criterion based on a finite difference
- approximation of the gradient.
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_10.html">Step-10</a></td>
- <td> Higher order mappings. Do not
- solve equations, but rather compute the value of pi to high
- accuracy.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_11.html">Step-11</a></td>
- <td> Solving a Laplace problem with
- higher order mappings. Using strange constraints and
- intermediate representations of sparsity patterns.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_12.html">Step-12</a></td>
- <td> Discontinuous Galerkin methods for linear advection problems.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_13.html">Step-13</a></td>
- <td> Software design questions and
- how to write a modular, extensible finite element program.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_14.html">Step-14</a></td>
- <td> Duality based error estimators,
- more strategies to write a modular, extensible finite element
- program.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_15.html">Step-15</a></td>
- <td> A nonlinear elliptic problem: The minimal surface equation.
- Newton's method. Transferring a solution across mesh refinement.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_16.html">Step-16</a></td>
- <td> Multigrid preconditioning of the Laplace equation on adaptive
- meshes.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_17.html">Step-17</a></td>
- <td> Using PETSc for linear algebra; running
- in parallel on clusters of computers linked together by MPI.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_18.html">Step-18</a></td>
- <td> A time dependent problem; using a much
- simplified version of implementing elasticity; moving meshes; handling
- large scale output of parallel programs.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_19.html">Step-19</a></td>
- <td> Input parameter file handling. Merging
- output of a parallel program.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_20.html">Step-20</a></td>
- <td> Mixed finite elements. Using block
- matrices and block vectors to define more complicated solvers and
- preconditioners working on the Schur complement.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_21.html">Step-21</a></td>
- <td> The time dependent two-phase flow in
- porous media. Extensions of mixed Laplace discretizations. More
- complicated block solvers. Simple time stepping.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_22.html">Step-22</a></td>
- <td> Solving the Stokes equations of slow fluid flow on adaptive
- meshes. More on Schur complement solvers. Advanced use of the
- ConstraintMatrix class.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_23.html">Step-23</a></td>
- <td> Finally a "real" time dependent problem, the wave equation.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_24.html">Step-24</a></td>
- <td> A variant of step-23 with absorbing
- boundary conditions, and extracting practically useful data.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_25.html">Step-25</a></td>
- <td> The sine-Gordon
- soliton equation, which is a nonlinear variant of the time
- dependent wave equation covered in step-23 and step-24.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_27.html">Step-27</a></td>
- <td> hp finite element methods </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_28.html">Step-28</a></td>
- <td> Multiple grids for solving a multigroup diffusion equation
- in nuclear physics simulating a nuclear reactor core </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_29.html">Step-29</a></td>
- <td> Solving a complex-valued Helmholtz equation. Sparse direct
- solvers. Dealing with parameter files. </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_30.html">Step-30</a></td>
- <td> Anisotropic refinement for DG finite element methods.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_31.html">Step-31</a></td>
- <td> Time-dependent Stokes flow driven by temperature
- differences in a fluid. Adaptive meshes that change between time
- steps.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_32.html">Step-32</a></td>
- <td> A massively parallel solver for time-dependent Stokes flow driven
- by temperature differences in a fluid. Adapting methods for real-world
- equations.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
- <td> A nonlinear hyperbolic conservation law: The Euler equations of
- compressible gas dynamics.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_34.html">Step-34</a></td>
- <td> Boundary element methods (BEM) of low order: Exterior irrotational
- flow. The ParsedFunction class.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_35.html">Step-35</a></td>
- <td> A projection solver for the Navier–Stokes equations.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_36.html">Step-36</a></td>
- <td> Using SLEPc for linear algebra; solving an eigenspectrum
- problem. The Schrödinger wave equation.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_37.html">Step-37</a></td>
- <td> Solving a Poisson problem with a multilevel preconditioner without
- explicitly storing the matrix (a matrix-free method).
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_38.html">Step-38</a></td>
- <td>Solving the Laplace-Beltrami equation on curved manifolds embedded
- in higher dimensional spaces.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_39.html">Step-39</a></td>
- <td> Solving Poisson's equation once more, this time with the
- interior penalty method, one of the discontinous Galerkin
- methods developed for this problem. Error estimator, adaptive
- meshes, and multigrid preconditioner, all using the MeshWorker
- framework.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_40.html">Step-40</a></td>
- <td> Techniques for the massively parallel solution of the Laplace
- equation (up to 10,000s of processors).
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_41.html">Step-41</a></td>
- <td> Solving the obstacle problem, a variational inequality.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_42.html">Step-42</a></td>
- <td> A solver for an elasto-plastic contact problem, running on
- parallel machines.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_43.html">Step-43</a></td>
- <td> Advanced techniques for the simulation of porous media flow.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_44.html">Step-44</a></td>
- <td> Finite strain hyperelasticity based on a three-field formulation.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_45.html">Step-45</a></td>
- <td> Periodic boundary conditions.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_46.html">Step-46</a></td>
- <td> Coupling different kinds of equations in different parts of the domain.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_48.html">Step-48</a></td>
- <td> Explicit time stepping for the Sine–Gordon equation based on
- a diagonal mass matrix. Efficient implementation of (nonlinear) finite
- element operators.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_49.html">Step-49</a></td>
- <td> Advanced mesh creation and manipulation techniques.
- </td></tr>
-
- <tr valign="top">
- <td><a href="../../doxygen/deal.II/step_51.html">Step-51</a></td>
- <td> Solving the convection-diffusion equation with a hyrbidizable
- discontinuous Galerkin method using face elements.
- </td></tr>
-</table>
-
-
-<!-- Page Foot -->
-<hr>
-<address>
-<a href="../../mail.html">The deal.II group</a></address>
-</body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Step-by-Step</title>
- <meta name="copyright" content="Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by the deal.II Authors">
- <meta name="date" content="$Date$">
- <meta name="svn_id" content="$Id$">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-
-<!-- Page Body -->
-<body lang="en">
-
-
-<h3>Tutorial programs grouped by topics</h3>
-
-<table align="center" width="90%">
- <tr valign="top">
- <td><b>Basic techniques</b></td>
- <td><a href="../../doxygen/deal.II/step_1.html">Step-1</a></td>
- <td> Creating a grid. A simple way to write it to a file
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_2.html">Step-2</a></td>
- <td> Degrees of freedom
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_3.html">Step-3</a></td>
- <td> Solve the Laplace equation
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_4.html">Step-4</a></td>
- <td> Dimension independent programming, non-zero data
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_5.html">Step-5</a></td>
- <td> Computing on uniformly refined meshes
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_6.html">Step-6</a></td>
- <td> Adaptivity
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_7.html">Step-7</a></td>
- <td> Evaluating errors
- </td>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_15.html">Step-15</a></td>
- <td> Nonlinear problems, Newton's method
- </td>
- </tr>
-
-
- <tr><td><br></td></tr>
-
- <tr valign="top">
- <td><b>Advanced techniques</b></td>
- <td>
- <a href="../../doxygen/deal.II/step_9.html">Step-9</a>,
- <a href="../../doxygen/deal.II/step_28.html">Step-28</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>,
- <a href="../../doxygen/deal.II/step_48.html">Step-48</a>,
- <a href="../../doxygen/deal.II/step_51.html">Step-51</a>
- </td>
- <td> Multithreading
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_20.html">Step-20</a>,
- <a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_22.html">Step-22</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>
- </td>
- <td> Block solvers and preconditioners
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_33.html">Step-33</a>,
- <a href="../../doxygen/deal.II/step_41.html">Step-41</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Using Trilinos
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_17.html">Step-17</a>,
- <a href="../../doxygen/deal.II/step_18.html">Step-18</a>,
- <a href="../../doxygen/deal.II/step_19.html">Step-19</a>,
- <a href="../../doxygen/deal.II/step_40.html">Step-40</a>
- </td>
- <td> Parallelization via PETSc and MPI
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>
- </td>
- <td> Parallelization via Trilinos and MPI
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_40.html">Step-40</a>,
- <a href="../../doxygen/deal.II/step_40.html">Step-42</a>
- </td>
- <td> Parallelization on very large numbers of processors
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_19.html">Step-19</a>,
- <a href="../../doxygen/deal.II/step_28.html">Step-28</a>,
- <a href="../../doxygen/deal.II/step_29.html">Step-29</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_29.html">Step-33</a>,
- <a href="../../doxygen/deal.II/step_34.html">Step-34</a>,
- <a href="../../doxygen/deal.II/step_35.html">Step-35</a>,
- <a href="../../doxygen/deal.II/step_36.html">Step-36</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>
- </td>
- <td> Input parameter handling
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_10.html">Step-10</a>,
- <a href="../../doxygen/deal.II/step_11.html">Step-11</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>
- </td>
- <td> Higher order mappings
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_6.html">Step-6</a>,
- <a href="../../doxygen/deal.II/step_9.html">Step-9</a>,
- <a href="../../doxygen/deal.II/step_14.html">Step-14</a>,
- <a href="../../doxygen/deal.II/step_39.html">Step-39</a>
- </td>
- <td> Error indicators and estimators
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_15.html">Step-15</a>,
- <a href="../../doxygen/deal.II/step_28.html">Step-28</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_33.html">Step-33</a>,
- <a href="../../doxygen/deal.II/step_40.html">Step-40</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Transferring solutions across mesh refinement
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_12.html">Step-12</a>,
- <a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_39.html">Step-39</a>,
- <a href="../../doxygen/deal.II/step_46.html">Step-46</a>,
- <a href="../../doxygen/deal.II/step_51.html">Step-51</a>
- </td>
- <td> Discontinuous Galerkin methods
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_27.html">Step-27</a>,
- <a href="../../doxygen/deal.II/step_46.html">Step-46</a>
- </td>
- <td> hp finite elements
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_30.html">Step-30</a></td>
- <td> Anisotropic refinement for DG finite element methods
- </td>
- </tr>
-
- <tr>
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_16.html">Step-16</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_39.html">Step-39</a>,
- <a href="../../doxygen/deal.II/step_41.html">Step-41</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Multilevel preconditioners
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
- <td> Computing Jacobians from residuals, automatic differentiation
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_34.html">Step-34</a>,
- <a href="../../doxygen/deal.II/step_38.html">Step-38</a>
- </td>
- <td> Boundary element methods, curved manifolds
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_45.html">Step-45</a>
- </td>
- <td> Periodic boundary conditions
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_37.html">Step-37</a>,
- <a href="../../doxygen/deal.II/step_48.html">Step-48</a>
- </td>
- <td> Matrix-free methods
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_49.html">Step-49</a>
- </td>
- <td> Advanced meshes
- </td>
- </tr>
-
- <tr><td><br></td></tr>
-
- <tr valign="top">
- <td><b>Linear solver issues</b></td>
- <td><a href="../../doxygen/deal.II/step_3.html">Step-3</a></td>
- <td> Conjugate Gradient solver
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td><a href="../../doxygen/deal.II/step_5.html">Step-5</a></td>
- <td> Preconditioned CG solver
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td><a href="../../doxygen/deal.II/step_9.html">Step-9</a></td>
- <td> BiCGStab
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td>
- <a href="../../doxygen/deal.II/step_16.html">Step-16</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_37.html">Step-37</a>,
- <a href="../../doxygen/deal.II/step_39.html">Step-39</a>,
- <a href="../../doxygen/deal.II/step_41.html">Step-41</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Multilevel preconditioners
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td>
- <a href="../../doxygen/deal.II/step_17.html">Step-17</a>,
- <a href="../../doxygen/deal.II/step_18.html">Step-18</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_40.html">Step-40</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>
- </td>
- <td> Parallel solvers
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td>
- <a href="../../doxygen/deal.II/step_20.html">Step-20</a>,
- <a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_22.html">Step-22</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Block and Schur complement solvers
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td><a href="../../doxygen/deal.II/step_35.html">Step-35</a></td>
- <td> Decoupled projection solvers
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td>
- <a href="../../doxygen/deal.II/step_33.html">Step-33</a>,
- <a href="../../doxygen/deal.II/step_41.html">Step-41</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>
- </td>
- <td> Linear Newton systems from nonlinear equations
- </td>
- </tr>
-
- <tr valign="top">
- <td><b></b></td>
- <td><a href="../../doxygen/deal.II/step_36.html">Step-36</a></td>
- <td> Eigenvalue solvers
- </td>
- </tr>
-
- <tr><td><br></td></tr>
-
- <tr valign="top">
- <td><b>Other equations</b></td>
- <td>
- <a href="../../doxygen/deal.II/step_7.html">Step-7</a>,
- <a href="../../doxygen/deal.II/step_29.html">Step-29</a>
- </td>
- <td> Helmholtz equation
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_8.html">Step-8</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>,
- <a href="../../doxygen/deal.II/step_46.html">Step-46</a>
- </td>
- <td> Elasticity and elasto-plasticity equations
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_15.html">Step-15</a>
- </td>
- <td> Minimal surface equation
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_18.html">Step-18</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>
- </td>
- <td> Quasi-static elasticity equations
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_9.html">Step-9</a>,
- <a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>,
- <a href="../../doxygen/deal.II/step_51.html">Step-51</a>
- </td>
- <td> Transport (advection) equations
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
- <td> The nonlinear hyperbolic Euler system of compressible gas dynamics
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_20.html">Step-20</a>,
- <a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Mixed Laplace, Darcy, Porous media
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_22.html">Step-22</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_35.html">Step-35</a>,
- <a href="../../doxygen/deal.II/step_46.html">Step-46</a>
- </td>
- <td> Stokes and incompressible Navier-Stokes flow
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_23.html">Step-23</a>,
- <a href="../../doxygen/deal.II/step_24.html">Step-24</a>,
- <a href="../../doxygen/deal.II/step_25.html">Step-25</a>,
- <a href="../../doxygen/deal.II/step_48.html">Step-48</a>
- </td>
- <td> The wave equation, in linear and nonlinear variants
- </td>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_28.html">Step-28</a></td>
- <td> A multigroup diffusion problem in neutron transport
- </td>
- </tr>
-
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_34.html">Step-34</a></td>
- <td> Irrotational flow
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_36.html">Step-36</a></td>
- <td> An eigenspectrum problem
- </tr>
-
- <tr valign="top">
- <td></td>
- <td>
- <a href="../../doxygen/deal.II/step_41.html">Step-41</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>
- </td>
- <td> The obstacle problem, a variational inequality
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_46.html">Step-46</a></td>
- <td> Coupling different equations in different parts of the domain
- </tr>
-
-
- <tr><td><br></td></tr>
-
-
- <tr valign="top">
- <td><b>Vector problems</b></td>
- <td>
- <a href="../../doxygen/deal.II/step_8.html">Step-8</a>,
- <a href="../../doxygen/deal.II/step_42.html">Step-42</a>
- </td>
- <td> Elasticity and elasto-plasticity equations
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_20.html">Step-20</a></td>
- <td> Mixed Laplace
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Mixed Laplace plus an advection equation
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_22.html">Step-22</a>,
- <a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>,
- <a href="../../doxygen/deal.II/step_35.html">Step-35</a></td>
- <td> Incompressible Stokes and Navier-Stokes flow
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_29.html">Step-29</a></td>
- <td> A complex-valued Helmholtz problem
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
- <td> The Euler equations of compressible gas dynamics
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_46.html">Step-46</a></td>
- <td> Coupling different equations in different parts of the domain
- </tr>
-
-
- <tr valign="top">
- <td><b>Time-dependent problems</b></td>
- <td>
- <a href="../../doxygen/deal.II/step_18.html">Step-18</a>,
- <a href="../../doxygen/deal.II/step_44.html">Step-44</a>
- </td>
- <td> Quasi-static elasticity
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_21.html">Step-21</a>,
- <a href="../../doxygen/deal.II/step_43.html">Step-43</a>
- </td>
- <td> Porous media flow
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_23.html">Step-23</a>,
- <a href="../../doxygen/deal.II/step_24.html">Step-24</a>,
- <a href="../../doxygen/deal.II/step_25.html">Step-25</a>,
- <a href="../../doxygen/deal.II/step_48.html">Step-48</a>
- </td>
- <td> The wave equation, in linear and nonlinear variants
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_31.html">Step-31</a>,
- <a href="../../doxygen/deal.II/step_32.html">Step-32</a>
- </td>
- <td> Time dependent Stokes flow driven by buoyancy
- </td>
- </tr>
-
- <tr valign="top">
- <td></td>
- <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
- <td> The Euler equations of compressible gas dynamics
- </td>
- </tr>
- </td>
-</table>
-
-<!-- Page Foot -->
-<hr>
-<address>
-<a href="../../mail.html">The deal.II group</a></address>
-</body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Step-by-Step</title>
- <meta name="copyright" content="Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2007, 2008, 2009, 2010 by the deal.II Authors">
- <meta name="date" content="$Date$">
- <meta name="svn_id" content="$Id$">
- <meta name="keywords" content="deal.II,deal.II tutorial,deal II">
-</head>
-
-<!-- Page Body -->
-<body lang="en">
-
-<a name="overview"></a>
-<h2>Overview</h2>
-
-<p><b>New to <acronym>deal.II</acronym>?</b> You might want to start with tutorial <a href="../../doxygen/deal.II/step_1.html">Step-1</a> and work your way up to Step-5.
-At that point you can explore what features you are interested in and look at the large collection
-of programs listed below.
-<p>
-
-<p>
-The <acronym>deal.II</acronym> tutorial contains a collection of
-programs, each more
-or less built atop of previous ones, which demonstrate various
-aspects of the library. Each such example has the following structure:
-<ol>
- <li> <b>Introduction:</b> What the program does, including
- the mathematical model, and
- what programming techniques are new.
- <li> <b>The commented program:</b> An extensively documented listing of the
- source code.
- <li> <b>Results:</b> The output of the program, with comments and
- interpretation.
- <li> <b>The plain program:</b> The source code stripped of
- all comments.
-</ol>
-</p>
-
-<p>
-You can browse the available tutorial programs
-<ol>
- <li> as <b><a href="#graph">a graph (see below)</a></b> that shows how tutorial programs build upon each other.
- <li> as <b><a href="toc-list.html">a list</a></b> that provides a short
- synopsis of each program.
- <li> or <b><a href="toc-topics.html">grouped by topic</a></b>.
-</ol>
-Some of the programs also jointly form
-the <a href="../../doxygen/deal.II/group__geodynamics.html">geodynamics
- demonstration suite</a>.
-</p>
-
-<p>
-The programs are in the <code>examples/</code> directory of your local deal.II
-installation. After compiling the library itself, if you go into one of the
-tutorial directories, you can compile
-the program by typing <strong>make</strong>, and run it
-using <strong>make run</strong>. The latter command also compiles the program
-if that has not already been done. The Makefiles in the different
-directories are based on the small program Makefile template described
-<a href="../../development/index.html" target="_top">in this section</a>.
-</p>
-
-
-<a name="graph"></a>
-<h3>Connections between tutorial programs</h3>
-
-The following graph shows the connections between tutorial programs and
-how they build on each other.
-Click on any of the boxes to go to one of the programs. If you hover
-your mouse pointer over a box, a brief description of the program
-should appear.
-
-<p align="center">
-<img src="steps.png" usemap="#StepsMap"\/>
-@@MAP@@
-</p>
-
-<p>
-Legend:
-<b>Green octagons:</b> programs that show basic techniques;
-<b>Orange boxes:</b> advanced techniques;
-<b>Yellow:</b> applications in fluid dynamics;
-<b>Light blue:</b> applications in solid mechanics;
-<b>Dark blue boxes:</b> time dependent problems.
-</p>
-
-<!-- Page Foot -->
-<hr>
-<address>
-<a href="../../mail.html">The deal.II group</a></address>
-</body>
-</html>
--- /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.
+//
+// ---------------------------------------------------------------------
+
+
+/**
+ * @page Tutorial Tutorial programs
+ *
+ * New to deal.II? You might want to start with tutorial Step-1 and work
+ * your way up to Step-5. At that point you can explore what features you
+ * are interested in and look at the large collection of programs listed
+ * below.
+ *
+ * The deal.II tutorial contains a collection of programs, each more or
+ * less built atop of previous ones, which demonstrate various aspects of
+ * the library. Each such example has the following structure:
+ * <ol>
+ * <li> <b>Introduction:</b> What the program does, including
+ * the mathematical model, and
+ * what programming techniques are new.
+ * <li> <b>The commented program:</b> An extensively documented listing of the
+ * source code.
+ * <li> <b>Results:</b> The output of the program, with comments and
+ * interpretation.
+ * <li> <b>The plain program:</b> The source code stripped of
+ * all comments.
+ * </ol>
+ * You can browse the available tutorial programs
+ * <ol>
+ * <li> as <b><a href="#graph">a graph</a></b> that shows how tutorial programs build upon each other.
+ * <li> as <b><a href="#list">a list</a></b> that provides a short
+ * synopsis of each program.
+ * <li> or <b><a href="#topic">grouped by topic</a></b>.
+ * </ol>
+ * Some of the programs also jointly form
+ * the <a href="../../doxygen/deal.II/group__geodynamics.html">geodynamics
+ * demonstration suite</a>.
+ *
+ * The programs are in the <code>examples/</code> directory of your local
+ * deal.II installation. After compiling the library itself, if you go into
+ * one of the tutorial directories, you can configure the program by typing
+ * <code>cmake .</code>, build it via <code>make</code> and run it using
+ * <code>make run</code>. The latter command also compiles the program if
+ * that has not already been done. The CMakefiles.txt files in the
+ * different directories are based on the small program Makefile template
+ * described <a href="../../user/cmakelists.html" target="_top">in this
+ * section</a>.
+ *
+ * <a name="graph"></a>
+ * <h3>Connections between tutorial programs</h3>
+ *
+ * The following graph shows the connections between tutorial programs and
+ * how they build on each other.
+ * Click on any of the boxes to go to one of the programs. If you hover
+ * your mouse pointer over a box, a brief description of the program
+ * should appear.
+ * @dot
+@@MAP@@
+ * @enddot
+ *
+ * Legend:<br />
+ * <b>Green octagons:</b> programs that show basic techniques;<br />
+ * <b>Orange boxes:</b> advanced techniques;<br />
+ * <b>Yellow:</b> applications in fluid dynamics;<br />
+ * <b>Light blue:</b> applications in solid mechanics;<br />
+ * <b>Dark blue boxes:</b> time dependent problems.
+ *
+ * <a name="list"></a>
+ * <h3>Tutorial programs listed by number</h3>
+ *
+ * <table align="center" width="90%">
+ * <tr valign="top">
+ * <td width="100px">Step-1</td>
+ * <td> Creating a grid. A simple way to write it to a file.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-2</td>
+ * <td> Associate degrees of freedom to
+ * each vertex and compute the resulting sparsity pattern of
+ * matrices. Show that renumbering reduces the bandwidth of
+ * matrices significantly, i.e. clusters nonzero entries around the
+ * diagonal.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-3</td>
+ * <td> Actually solve Laplace's
+ * problem. Object-orientation. Assembling matrices and
+ * vectors. Boundary values.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-4</td>
+ * <td> This example is programmed in a
+ * way that it is independent of the dimension for which we want to
+ * solve Laplace's equation; we will solve the equation in 2D and
+ * 3D, although the program is exactly the same. Non-constant right
+ * hand side function. Non-homogeneous boundary values.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-5</td>
+ * <td> Computations on successively
+ * refined grids. Reading a grid from disk. Some optimizations.
+ * Using assertions. Non-constant coefficient in
+ * the elliptic operator (yielding the extended Poisson
+ * equation). Preconditioning the CG solver for the
+ * linear system of equations.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-6</td>
+ * <td> Adaptive local
+ * refinement. Handling of hanging nodes. Higher order elements.
+ * Catching exceptions in the <code>main</code>; function.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-7</td>
+ * <td> Helmholtz
+ * equation. Non-homogeneous Neumann boundary conditions and
+ * boundary integrals. Verification of correctness of computed
+ * solutions. Computing the error between exact and numerical
+ * solution and output of the data in tables. Using counted pointers.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-8</td>
+ * <td> The elasticity equations will be
+ * solved instead of Laplace's equation. The solution is
+ * vector-valued and the equations form a system with as many
+ * equations as the dimension of the space in which it is posed.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-9</td>
+ * <td> Linear advection equation, assembling
+ * the system of equations in parallel using multi-threading,
+ * implementing a refinement criterion based on a finite difference
+ * approximation of the gradient.
+ *
+ * <tr valign="top">
+ * <td>Step-10</td>
+ * <td> Higher order mappings. Do not
+ * solve equations, but rather compute the value of pi to high
+ * accuracy.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-11</td>
+ * <td> Solving a Laplace problem with
+ * higher order mappings. Using strange constraints and
+ * intermediate representations of sparsity patterns.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-12</td>
+ * <td> Discontinuous Galerkin methods for linear advection problems.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-13</td>
+ * <td> Software design questions and
+ * how to write a modular, extensible finite element program.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-14</td>
+ * <td> Duality based error estimators,
+ * more strategies to write a modular, extensible finite element
+ * program.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-15</td>
+ * <td> A nonlinear elliptic problem: The minimal surface equation.
+ * Newton's method. Transferring a solution across mesh refinement.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-16</td>
+ * <td> Multigrid preconditioning of the Laplace equation on adaptive
+ * meshes.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-17</td>
+ * <td> Using PETSc for linear algebra; running
+ * in parallel on clusters of computers linked together by MPI.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-18</td>
+ * <td> A time dependent problem; using a much
+ * simplified version of implementing elasticity; moving meshes; handling
+ * large scale output of parallel programs.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-19</td>
+ * <td> Input parameter file handling. Merging
+ * output of a parallel program.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-20</td>
+ * <td> Mixed finite elements. Using block
+ * matrices and block vectors to define more complicated solvers and
+ * preconditioners working on the Schur complement.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-21</td>
+ * <td> The time dependent two-phase flow in
+ * porous media. Extensions of mixed Laplace discretizations. More
+ * complicated block solvers. Simple time stepping.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-22</td>
+ * <td> Solving the Stokes equations of slow fluid flow on adaptive
+ * meshes. More on Schur complement solvers. Advanced use of the
+ * ConstraintMatrix class.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-23</td>
+ * <td> Finally a "real" time dependent problem, the wave equation.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-24</td>
+ * <td> A variant of step-23 with absorbing
+ * boundary conditions, and extracting practically useful data.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-25</td>
+ * <td> The sine-Gordon
+ * soliton equation, which is a nonlinear variant of the time
+ * dependent wave equation covered in step-23 and step-24.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-27</td>
+ * <td> hp finite element methods </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-28</td>
+ * <td> Multiple grids for solving a multigroup diffusion equation
+ * in nuclear physics simulating a nuclear reactor core </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-29</td>
+ * <td> Solving a complex-valued Helmholtz equation. Sparse direct
+ * solvers. Dealing with parameter files. </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-30</td>
+ * <td> Anisotropic refinement for DG finite element methods.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-31</td>
+ * <td> Time-dependent Stokes flow driven by temperature
+ * differences in a fluid. Adaptive meshes that change between time
+ * steps.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-32</td>
+ * <td> A massively parallel solver for time-dependent Stokes flow driven
+ * by temperature differences in a fluid. Adapting methods for real-world
+ * equations.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-33</td>
+ * <td> A nonlinear hyperbolic conservation law: The Euler equations of
+ * compressible gas dynamics.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-34</td>
+ * <td> Boundary element methods (BEM) of low order: Exterior irrotational
+ * flow. The ParsedFunction class.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-35</td>
+ * <td> A projection solver for the Navier–Stokes equations.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-36</td>
+ * <td> Using SLEPc for linear algebra; solving an eigenspectrum
+ * problem. The Schrödinger wave equation.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-37</td>
+ * <td> Solving a Poisson problem with a multilevel preconditioner without
+ * explicitly storing the matrix (a matrix-free method).
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-38</td>
+ * <td>Solving the Laplace-Beltrami equation on curved manifolds embedded
+ * in higher dimensional spaces.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-39</td>
+ * <td> Solving Poisson's equation once more, this time with the
+ * interior penalty method, one of the discontinous Galerkin
+ * methods developed for this problem. Error estimator, adaptive
+ * meshes, and multigrid preconditioner, all using the MeshWorker
+ * framework.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-40</td>
+ * <td> Techniques for the massively parallel solution of the Laplace
+ * equation (up to 10,000s of processors).
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-41</td>
+ * <td> Solving the obstacle problem, a variational inequality.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-42</td>
+ * <td> A solver for an elasto-plastic contact problem, running on
+ * parallel machines.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-43</td>
+ * <td> Advanced techniques for the simulation of porous media flow.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-44</td>
+ * <td> Finite strain hyperelasticity based on a three-field formulation.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-45</td>
+ * <td> Periodic boundary conditions.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-46</td>
+ * <td> Coupling different kinds of equations in different parts of the domain.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-48</td>
+ * <td> Explicit time stepping for the Sine–Gordon equation based on
+ * a diagonal mass matrix. Efficient implementation of (nonlinear) finite
+ * element operators.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-49</td>
+ * <td> Advanced mesh creation and manipulation techniques.
+ * </td></tr>
+ *
+ * <tr valign="top">
+ * <td>Step-51</td>
+ * <td> Solving the convection-diffusion equation with a hyrbidizable
+ * discontinuous Galerkin method using face elements.
+ * </td></tr>
+ * </table>
+ *
+ * <a name="topic"></a>
+ * <h3>Tutorial programs grouped by topics</h3>
+ *
+ * <h4><b>Basic techniques</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Creating a grid. A simple way to write it to a file
+ * <td>Step-1</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Degrees of freedom
+ * <td>Step-2</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Solve the Laplace equation
+ * <td>Step-3</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Dimension independent programming, non-zero data
+ * <td>Step-4</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Computing on uniformly refined meshes
+ * <td>Step-5</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Adaptivity
+ * <td>Step-6</td>
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Evaluating errors
+ * <td>Step-7</td>
+ * </td>
+ *
+ * <tr valign="top">
+ * <td> Nonlinear problems, Newton's method
+ * </td>
+ * <td>Step-15</td>
+ * </tr>
+ *
+ * </table>
+ * <h4><b>Advanced techniques</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Multithreading
+ * </td>
+ * <td>
+ * Step-9,
+ * Step-28,
+ * Step-32,
+ * Step-44,
+ * Step-48,
+ * Step-51
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Block solvers and preconditioners
+ * </td>
+ * <td>
+ * Step-20,
+ * Step-21,
+ * Step-22,
+ * Step-31,
+ * Step-32,
+ * Step-43,
+ * Step-44
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Using Trilinos
+ * </td>
+ * <td>
+ * Step-31,
+ * Step-32,
+ * Step-33,
+ * Step-41,
+ * Step-42,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Parallelization via PETSc and MPI
+ * </td>
+ * <td>
+ * Step-17,
+ * Step-18,
+ * Step-19,
+ * Step-40
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Parallelization via Trilinos and MPI
+ * </td>
+ * <td>
+ * Step-32,
+ * Step-42
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Parallelization on very large numbers of processors
+ * </td>
+ * <td>
+ * Step-32,
+ * Step-40,
+ * Step-42
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Input parameter handling
+ * </td>
+ * <td>
+ * Step-19,
+ * Step-28,
+ * Step-29,
+ * Step-32,
+ * Step-33,
+ * Step-34,
+ * Step-35,
+ * Step-36,
+ * Step-42,
+ * Step-44
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Higher order mappings
+ * </td>
+ * <td>
+ * Step-10,
+ * Step-11,
+ * Step-32
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Error indicators and estimators
+ * </td>
+ * <td>
+ * Step-6,
+ * Step-9,
+ * Step-14,
+ * Step-39
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Transferring solutions across mesh refinement
+ * </td>
+ * <td>
+ * Step-15,
+ * Step-28,
+ * Step-31,
+ * Step-32,
+ * Step-33,
+ * Step-40,
+ * Step-42,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Discontinuous Galerkin methods
+ * </td>
+ * <td>
+ * Step-12,
+ * Step-21,
+ * Step-39,
+ * Step-46,
+ * Step-51
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> hp finite elements
+ * </td>
+ * <td>
+ * Step-27,
+ * Step-46
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Anisotropic refinement for DG finite element methods
+ * </td>
+ * <td>Step-30</td>
+ * </tr>
+ *
+ * <tr>
+ * <td> Multilevel preconditioners
+ * </td>
+ * <td>
+ * Step-16,
+ * Step-31,
+ * Step-32,
+ * Step-39,
+ * Step-41,
+ * Step-42,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Computing Jacobians from residuals, automatic differentiation
+ * </td>
+ * <td>Step-33</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Boundary element methods, curved manifolds
+ * </td>
+ * <td>
+ * Step-32,
+ * Step-34,
+ * Step-38
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Periodic boundary conditions
+ * </td>
+ * <td>
+ * Step-45
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Matrix-free methods
+ * </td>
+ * <td>
+ * Step-37,
+ * Step-48
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Advanced meshes
+ * </td>
+ * <td>
+ * Step-49
+ * </td>
+ * </tr>
+ *
+ * </table>
+ * <h4><b>Linear solvers</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Conjugate Gradient solver
+ * </td>
+ * <td>Step-3</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Preconditioned CG solver
+ * </td>
+ * <td>Step-5</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> BiCGStab
+ * </td>
+ * <td>Step-9</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Multilevel preconditioners
+ * </td>
+ * <td>
+ * Step-16,
+ * Step-31,
+ * Step-32,
+ * Step-37,
+ * Step-39,
+ * Step-41,
+ * Step-42,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Parallel solvers
+ * </td>
+ * <td>
+ * Step-17,
+ * Step-18,
+ * Step-32,
+ * Step-40,
+ * Step-42
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Block and Schur complement solvers
+ * </td>
+ * <td>
+ * Step-20,
+ * Step-21,
+ * Step-22,
+ * Step-31,
+ * Step-32,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Decoupled projection solvers
+ * </td>
+ * <td>Step-35</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Linear Newton systems from nonlinear equations
+ * </td>
+ * <td>
+ * Step-33,
+ * Step-41,
+ * Step-42,
+ * Step-44
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Eigenvalue solvers
+ * </td>
+ * <td>Step-36</td>
+ * </tr>
+ *
+ * </table>
+ * <h4><b>Other equations</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Helmholtz equation
+ * </td>
+ * <td>
+ * Step-7,
+ * Step-29
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Elasticity and elasto-plasticity equations
+ * </td>
+ * <td>
+ * Step-8,
+ * Step-42,
+ * Step-46
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Minimal surface equation
+ * </td>
+ * <td>
+ * Step-15
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Quasi-static elasticity equations
+ * </td>
+ * <td>
+ * Step-18,
+ * Step-44
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Transport (advection) equations
+ * </td>
+ * <td>Step-9,
+ * Step-21,
+ * Step-31,
+ * Step-32,
+ * Step-43,
+ * Step-51
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The nonlinear hyperbolic Euler system of compressible gas dynamics
+ * </td>
+ * <td>Step-33</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Mixed Laplace, Darcy, Porous media
+ * </td>
+ * <td>
+ * Step-20,
+ * Step-21,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Stokes and incompressible Navier-Stokes flow
+ * </td>
+ * <td>
+ * Step-22,
+ * Step-31,
+ * Step-32,
+ * Step-35,
+ * Step-46
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The wave equation, in linear and nonlinear variants
+ * </td>
+ * <td>
+ * Step-23,
+ * Step-24,
+ * Step-25,
+ * Step-48
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> A multigroup diffusion problem in neutron transport
+ * </td>
+ * <td>Step-28</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Irrotational flow
+ * </td>
+ * <td>Step-34</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> An eigenspectrum problem
+ * </td>
+ * <td>Step-36</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The obstacle problem, a variational inequality
+ * </td>
+ * <td>
+ * Step-41,
+ * Step-42
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Coupling different equations in different parts of the domain
+ * </td>
+ * <td>Step-46</td>
+ * </tr>
+ *
+ * </table>
+ * <h4><b>Vector problems</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Elasticity and elasto-plasticity equations
+ * </td>
+ * <td>
+ * Step-8,
+ * Step-42
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Mixed Laplace
+ * </td>
+ * <td>Step-20</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Mixed Laplace plus an advection equation
+ * </td>
+ * <td>Step-21,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Incompressible Stokes and Navier-Stokes flow
+ * </td>
+ * <td>Step-22,
+ * Step-31,
+ * Step-32,
+ * Step-35</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> A complex-valued Helmholtz problem
+ * </td>
+ * <td>Step-29</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The Euler equations of compressible gas dynamics
+ * </td>
+ * <td>Step-33</td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Coupling different equations in different parts of the domain
+ * <td>Step-46</td>
+ * </tr>
+ *
+ * </table>
+ * <h4><b>Time dependent problems</b></h4>
+ * <table align="center" width="90%">
+ *
+ * <tr valign="top">
+ * <td width="400px"> Quasi-static elasticity
+ * </td>
+ * <td>
+ * Step-18,
+ * Step-44
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Porous media flow
+ * </td>
+ * <td>Step-21,
+ * Step-43
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The wave equation, in linear and nonlinear variants
+ * </td>
+ * <td>Step-23,
+ * Step-24,
+ * Step-25,
+ * Step-48
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> Time dependent Stokes flow driven by buoyancy
+ * </td>
+ * <td>Step-31,
+ * Step-32
+ * </td>
+ * </tr>
+ *
+ * <tr valign="top">
+ * <td> The Euler equations of compressible gas dynamics
+ * </td>
+ * <td>Step-33</td>
+ * </tr>
+ * </table>
+ */
<b><small>Doxygen and Lectures</small></b>
<p>
- <a href="doxygen/tutorial/index.html" target="_top">Tutorial</a><br />
+ <a href="doxygen/deal.II/Tutorial.html" target="_top">Tutorial</a><br />
<a href="doxygen/deal.II/index.html" target="_top">Manual</a><br />
<a href="http://www.math.tamu.edu/~bangerth/videos.html"
target="_top">Wolfgang's lectures</a><br />
</p>
<ol>
+ <li> Removed: With the switch of the testsuite to CMake, the old report_features
+ and build test facilities are removed.
+ <br>
+ (Matthias Maier, 2013/12/03)
+ </li>
+
<li>
Changed: The kinds of template arguments for the VectorTools::interpolate
function taking a Mapping as first argument has changed. This was done to
<ol>
+ <li> Improved: The build system now supports usage of the library
+ out of the build directory without prior installation. This is done by
+ exporting an additional project configuration just for the build directory.
+ Furthermore, a bunch of convenience targets get now defined that just build
+ individual components (such as just the documentation or the libraries), and
+ if <tt>CMAKE_INSTALL_PREFIX</tt> is set, also install that specific component.
+ <br>
+ (Matthias Maier, Luca Heltai, 2013/12/03)
+ </li>
+
<li> Fixed: Missing instantiations of SparseDirectMUMPS have been added.
<br>
(Timo Heister, 2013/11/25)
<h3>Specific improvements</h3>
<ol>
+ <li> Fixed: Several functions in namespace GridTools were not instantiated
+ for parallel::distributed::Triangulation objects. This is now fixed.
+ <br>
+ (Denis Davydov, Wolfgang Bangerth, 2013/12/01)
+ </li>
+
+ <li> Improved: The methods ConstraintMatrix::distribute_local_to_global
+ now use scratch data that is private to each thread instead of allocating
+ it for every cell anew. This gives better performance, in particular in
+ parallel, of these operations, while maintaining thread-safety (when
+ accessing non-overlapping rows, no race condition can exist).
+ <br>
+ (Martin Kronbichler, 2013/12/03)
+ </li>
+
<li> Improved: When attempting operations such as FEValues::get_function_values()
or FEValues::shape_value(), the FEValues object needs to know that what these
functions return has been computed previously. What is computed is specified
</li>
</ul>
+
+
+ <a name="2014"> </a>
+ <h2>Publications in 2014</h2>
+
+ <!-- Please enter alphabetically by name -->
+ <ol>
+ <li> T. Wick, G. Singh, M.F. Wheeler
+ <br>
+ <strong>Pressurized-Fracture propagation using a phase-field approach coupled to a reservoir simulator
+ </strong>
+ <br>
+ SPE 168597-MS, SPE HFTC Proc. 2014.
+ </li>
+ </ol>
+
+
<a name="2013"> </a>
<h2>Publications in 2013</h2>
Journal of Elasticity, in press, 2013.
</li>
+ <li> S. Frei, T. Richter, T. Wick
+ <br>
+ <strong>Eulerian Techniques for Fluid-Structure Interactions - Part
+ I: Modeling and Simulation
+ </strong>
+ <br>
+ ENUMATH Proc., submitted Nov 2013.
+ </li>
+
+ <li> S. Frei, T. Richter, T. Wick
+ <br>
+ <strong>Eulerian Techniques for Fluid-Structure Interactions - Part II: Applications
+ </strong>
+ <br>
+ ENUMATH Proc., submitted Nov 2013.
+ </li>
+
<li> A. Geringer, B. Lenhof, S. Diebels
<br>
<strong>Macroscopic modeling of foams: an order-parameter
PhD thesis, University of Siegen, Germany, 2013.
</li>
+ <li> K. Kumar, T. van Noorden, M. F. Wheeler, T. Wick
+ <br>
+ <strong>An ALE-based method for reaction-induced boundary movement towards clogging
+ </strong>
+ <br>
+ ENUMATH Proc., submitted Nov 2013.
+ </li>
+
<li> K. Kumar, M.F. Wheeler, T. Wick
<br>
- <strong>Reactive flow in a thin channel
-and reaction-induced boundary movement in
-a monolithic ALE framework
+ <strong>Reactive flow reaction-induced boundary movement in
+ a thin channel
</strong>
<br>
- submitted to SISC, 2013.
+ SIAM J. Sci. Comput. 35(6), pp. B1235-B1266, 2013
</li>
<li> B. Lenhof, A. Geringer, S. Diebels
pp. 41-46, 2013.
</li>
+ <li> T. Richter, T. Wick
+ <br>
+ <strong>Solid growth and clogging in fluid-structure interaction computed in ALE and fully Eulerian coordinates
+ </strong>
+ <br>
+ submitted Oct 2013 (peer-reviewed journal)
+ </li>
+
+ <li> T. Richter, T. Wick
+ <br>
+ <strong>On time discretizations of fluid-structure interactions
+ </strong>
+ <br>
+ submitted Oct 2013 (book proceedings)
+ </li>
+
+
<li> T. Richter, T. Wick
<br>
<strong>Optimal Control and Parameter Estimation for Stationary Fluid-Structure Interaction Problems
</strong>
<br>
- SISC, accepted in May, 2013.
+ SIAM J. Sci. Comput., accepted in May, 2013.
</li>
<li> S. Roy, L. Heltai, D. Drapaca, F. Costanzo
ARMA Conference in San Francisco, Jun 23-26, 2013.
</li>
+
+
<li> J. Weinbub, K. Rupp, S. Selberherr
<br>
<strong>ViennaX: a parallel plugin execution framework for
and Mesh Adaptivity
</strong>
<br>
- Comp. Mech., DOI: 10.1007/s00466-013-0890-3, 2013.
+ Computational Mechanics, DOI: 10.1007/s00466-013-0890-3, 2013.
</li>
<li> T. Wick
methods for fluid-structure interaction computations
</strong>
<br>
- Comp. Mech., DOI: 10.1007/s00466-013-0866-3, 2013.
+ Computational Mechanics, DOI: 10.1007/s00466-013-0866-3, 2013.
</li>
<li> T. Wick
At this point, you have generated everything necessary to write
programs based on <acronym>deal.II</acronym>. If you are new to
<acronym>deal.II</acronym>, you may want to continue with the
- <a href="doxygen/tutorial/index.html" target="_top">tutorial</a>.
+ <a href="doxygen/deal.II/Tutorial.html" target="_top">tutorial</a>.
</p>
<a name="documentation"></a>
install both this readme, other installation instructions, as well as the
<a href="doxygen/deal.II/index.html" target="_top">manual that documents
all functions and classes</a> as well as
- the <a href="doxygen/tutorial/index.html" target="_top"> tutorial
+ the <a href="doxygen/deal.II/Tutorial.html" target="_top"> tutorial
of well-documented example programs</a> (the "steps").
</p>
}
table.navbar { }
-table.tutorial {
- color: black;
- border: 1px solid #aaa;
- background-color: #f9f9f9;
- padding: 5px;
- font-size: 95%;
-}
-div.tutorial {
- color: black;
- border: 1px solid #aaa;
- background-color: #f9f9f9;
- padding: 50px;
- font-size: 95%;
-}
strong.red { color: #ff0000; }
code.program { color: #700000; }
<h3>Primary build targets</h3>
<p> The current list of primary build targets can be queried via
- <code>make info</code>:
+ <code>make help</code>:
<pre class="cmake">
###
#
# The following targets are available (invoke via $ make <target>):
#
-# all - compiles the library and all enabled components
-# clean - removes all generated files
-# install - installs into CMAKE_INSTALL_PREFIX
-# help - prints a list of valid top level targets
-# info - prints this help message
+# all - compile the library and all enabled components
+# clean - remove all generated files
+# install - install into CMAKE_INSTALL_PREFIX
+# help - print this help message in the toplevel directory,
+# otherwise print a list of targets (in subdirectories)
#
-# edit_cache - runs ccmake for changing (cached) configuration variables
+# edit_cache - run ccmake for changing (cached) configuration variables
# and reruns the configure and generate phases of CMake
-# rebuild_cache - reruns the configure and generate phases of CMake
+# rebuild_cache - rerun the configure and generate phases of CMake
#
-# compat_files - builds and installs the 'compat_files' component
-# documentation - builds and installs the 'documentation' component
-# examples - builds and installs the 'examples' component
-# library - builds and installs the 'library' component
-# mesh_converter - builds and installs the 'mesh_converter' component
-# parameter_gui - builds and installs the 'parameter_gui' component
+# compat_files - build and install component 'compat_files'
+# documentation - build and install component 'documentation'
+# examples - build and install component 'examples'
+# library - build and install component 'library'
+# mesh_converter - build and install component 'mesh_converter'
+# parameter_gui - build and install component 'parameter_gui'
#
-# test - runs a minimal set of tests
+# test - run a minimal set of tests
#
-# setup_test - sets up the testsuite subprojects
-# clean_test - runs the 'clean' target in every testsuite subproject
-# prune_test - removes all testsuite subprojects
+# setup_tests - set up the testsuite subprojects
+# regen_tests - rerun configure stage in every testsuite subprojects
+# clean_tests - run the 'clean' target in every testsuite subproject
+# prune_tests - remove all testsuite subprojects
#
###
</pre>
#
# Detailed information (compiler flags, feature configuration) can be found in detailed.log
#
-# Run $ make info to print a help message with a list of top level targets
+# Run $ make help to print a help message with a list of top level targets
#
###
</pre>
common/Make.global_options
common/scripts/expand_instantiations
common/scripts/make_dependencies
- common/scripts/report_features
</pre>
Therefore, it should be sufficient to set <code>D</code> in the old
<b><small>Doxygen</small></b>
<p>
- <a href="../doxygen/tutorial/index.html" target="_top">Tutorial</a><br />
+ <a href="../doxygen/deal.II/Tutorial.html" target="_top">Tutorial</a><br />
<a href="../doxygen/deal.II/index.html" target="_top">Manual</a><br />
<a href="http://www.math.tamu.edu/~bangerth/videos.html"
target="_top">Wolfgang's lectures</a><br />
<h2>Tutorials</h2>
<p>
- The <a href="../doxygen/tutorial/index.html"
+ The <a href="../doxygen/deal.II/Tutorial.html"
target="_top">tutorial</a> is for new users of the
library. It explains the basic elements of finite element
programs based on the library, and provides small example
## ---------------------------------------------------------------------
IF(DEAL_II_COMPONENT_EXAMPLES)
+ MESSAGE(STATUS "Setup examples")
+
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION ${DEAL_II_EXAMPLES_RELDIR}
COMPONENT examples
PATTERN "untitled.geo" # step-49
PATTERN "untitled.msh" # step-49
)
+
+ MESSAGE(STATUS "Setup examples - Done")
ENDIF()
// to the vertex we consider at present, as they may or may not be ordered
// in the same order.
//
+ // This inconvenience could be avoided if finite elements have support
+ // points on vertices (which the one here has; for the concept of support
+ // points, see @ref GlossSupport "support points"). For such a case, one
+ // could construct a custom quadrature rule using
+ // FiniteElement::get_unit_support_points(). The first
+ // <code>GeometryInfo@<dim@>::vertices_per_cell*fe.dofs_per_vertex</code>
+ // quadrature points will then correspond to the vertices of the cell and
+ // are ordered consistent with <code>cell-@>vertex(i)</code>, taking into
+ // account that support points for vector elements will be duplicated
+ // <code>fe.dofs_per_vertex</code> times.
+ //
// Another point worth explaining about this short function is the way in
// which the triangulation class exports information about its vertices:
// through the <code>Triangulation::n_vertices</code> function, it
Rather facetiously, the sine-Gordon equation's moniker is a pun on the
so-called Klein-Gordon equation, which is a relativistic version of
-the Schrödinger equation for particles with non-zero mass. The resemblance is not just
+the Schrödinger equation for particles with non-zero mass. The resemblance is not just
superficial, the sine-Gordon equation has been shown to model some
unified-field phenomena such as interaction of subatomic particles
(see, e.g., Perring & Skyrme in Nuclear Physics <b>31</b>) and the
<h1>Introduction</h1>
The basic equation of stationary quantum mechanics is the
-Schrödinger equation which models the motion of particles in an
+Schrödinger equation which models the motion of particles in an
external potential $V(\mathbf x)$. The particle is described by a wave
function $\Psi(\mathbf x)$ that satisfies a relation of the
(nondimensionalized) form
-Finding eigenvalues of the Schrödinger equation.
+Finding eigenvalues of the Schrödinger equation.
-Matrix-free methods. Multigrid. Cell-based finite element operator.
+Matrix-free methods. Multigrid. Fast assembly techniques.
<br>
-<i>This program was contributed by Jörg Frohne (University of Siegen,
+<i>This program was contributed by Jörg Frohne (University of Siegen,
Germany) while on a long-term visit to Texas A&M University.
<br>
This material is based upon work partly supported by ThyssenKrupp Steel Europe.
<br>
-<i>This program was contributed by Jörg Frohne (University of Siegen,
+<i>This program was contributed by Jörg Frohne (University of Siegen,
Germany) while on a long-term visit to Texas A&M University, with significant
contributions by Timo Heister and Wolfgang Bangerth.
<br>
<ul>
<li> Extend the program from a static to a quasi-static situation, perhaps by
choosing a backward-Euler-scheme for the time discretization. Some theoretical
-results can be found in the PhD thesis by Jörg Frohne, <i>FEM-Simulation
+results can be found in the PhD thesis by Jörg Frohne, <i>FEM-Simulation
der Umformtechnik metallischer Oberflächen im Mikrokosmos</i>, University
of Siegen, Germany, 2011.
-Parallelization via MPI. The wave equation, in linear and nonlinear variants. Mass lumping. Cell-based finite element operator.
+Parallelization via MPI. The wave equation, in linear and nonlinear variants. Mass lumping. Fast assembly techniques.
/**
* Return all components of a
- * vector-valued function at a
- * given point.
+ * vector-valued function at the
+ * given point @p p.
*
* <tt>values</tt> shall have the
* right size beforehand,
void parse_parameters(ParameterHandler &prm);
/**
- * Get one value at the given
- * point.
+ * Return all components of a
+ * vector-valued function at the
+ * given point @p p.
*/
virtual void vector_value (const Point<dim> &p,
Vector<double> &values) const;
* The object with which we do
* computations.
*/
- FunctionParser<dim> function_object;
+ FunctionParse<dim> function_object;
};
}
/**
- * Join faces in the p4est forest due to periodic boundary conditions.
+ * Join faces in the p4est forest for periodic boundary conditions. As a
+ * result, each pair of faces will differ by at most one refinement level
+ * and ghost neighbors will be available across these faces.
*
* The vector can be filled by the function
* GridTools::collect_periodic_faces.
*
* @todo At the moment just default orientation is implemented.
*
- * @note Before this function can be used the triangulation has to be
+ * @note Before this function can be used the Triangulation has to be
* initialized and must not be refined.
* Calling this function more than once is possible, but not recommended:
- * The function destroys and rebuilds the p4est forest each time it is called.
+ * The function destroys and rebuilds the p4est forest each time it is
+ * called.
*/
void
add_periodicity
* FEValues<dim> fe_values (mapping, fe, dummy_quadrature,
* update_quadrature_points);
* fe_values.reinit (cell);
- * Point<dim>& mapped_point = fe_values.quadrature_point (i);
+ * Point<dim> mapped_point = fe_values.quadrature_point (i);
* @endcode
*
* Alternatively, the points can be transformed one-by-one:
* @code
- * const vector<Point<dim> >& unit_points =
+ * const vector<Point<dim> > &unit_points =
* fe.get_unit_support_points();
*
* Point<dim> mapped_point =
* If the mapping of all support points is needed, the first variant should
* be preferred for efficiency.
*
+ * @note Finite elements' implementation of the get_unit_support_points()
+ * returns these points in the same order as shape functions. As a consequence,
+ * the quadrature points accessed above are also ordered in this way. The
+ * order of shape functions is typically documented in the class documentation
+ * of the various finite element classes.
+ *
+ *
* <h3>Notes on the implementation of derived classes</h3>
*
* The following sections list the information to be provided by
/**
* Return the support points of the trial functions on the unit cell, if the
- * derived finite element defines some. Finite elements that allow some
+ * derived finite element defines them. Finite elements that allow some
* kind of interpolation operation usually have support points. On the other
* hand, elements that define their degrees of freedom by, for example,
* moments on faces, or as derivatives, don't have support points. In that
* function.
*
* See the class documentation for details on support points.
+ *
+ * @note Finite elements' implementation of this function
+ * returns these points in the same order as shape functions. The
+ * order of shape functions is typically documented in the class documentation
+ * of the various finite element classes. In particular, shape functions (and
+ * consequently the mapped quadrature points discussed in the class documentation
+ * of this class) will then traverse first those shape functions
+ * located on vertices, then on lines, then on quads, etc.
+ *
+ * @note If this element implements support points, then it will return one
+ * such point per shape function. Since multiple shape functions may be defined
+ * at the same location, the support points returned here may be duplicated. An
+ * example would be an element of the kind <code>FESystem(FE_Q(1),3)</code>
+ * for which each support point would appear three times in the returned array.
*/
const std::vector<Point<dim> > &
get_unit_support_points () const;
/**
- * This function will collect periodic face pairs on the highest (i.e.
- * coarsest) mesh level.
+ * This function will collect periodic face pairs on the
+ * coarsest mesh level of the given @p container (a Triangulation or DoFHandler).
*
* Define a 'first' boundary as all boundary faces having boundary_id
* @p b_id1 and a 'second' boundary consisting of all faces belonging
*
* @author Daniel Arndt, Matthias Maier, 2013
*/
- template<typename DH>
- std::vector<PeriodicFacePair<typename DH::cell_iterator> >
+ template<typename CONTAINER>
+ std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> >
collect_periodic_faces
- (const DH &dof_handler,
+ (const CONTAINER &container,
const types::boundary_id b_id1,
const types::boundary_id b_id2,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset = dealii::Tensor<1,DH::space_dimension>());
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>());
/**
* face with local face index <code>2*dimension+1</code> and boundary
* indicator @p b_id.
*
- * This function will collect periodic face pairs on the highest (i.e.
- * coarsest) mesh level.
+ * This function will collect periodic face pairs on the coarsest mesh level.
*
* @note This version of collect_periodic_face_pairs will not work on
* meshes with cells not in @ref GlossFaceOrientation
*
* @author Daniel Arndt, Matthias Maier, 2013
*/
- template<typename DH>
- std::vector<PeriodicFacePair<typename DH::cell_iterator> >
+ template<typename CONTAINER>
+ std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> >
collect_periodic_faces
- (const DH &dof_handler,
+ (const CONTAINER &container,
const types::boundary_id b_id,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset = dealii::Tensor<1,DH::space_dimension>());
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>());
/**
#include <deal.II/base/index_set.h>
#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
+#include <deal.II/base/thread_local_storage.h>
#include <deal.II/lac/vector.h>
typedef types::global_dof_index size_type;
/**
- * An enum that describes what should
- * happen if the two ConstraintMatrix
- * objects involved in a call to the
- * merge() function happen to have
- * constraints on the same degrees of
- * freedom.
+ * An enum that describes what should happen if the two ConstraintMatrix
+ * objects involved in a call to the merge() function happen to have
+ * constraints on the same degrees of freedom.
*/
enum MergeConflictBehavior
{
/**
- * Throw an exception if the two
- * objects concerned have
- * conflicting constraints on the
- * same degree of freedom.
+ * Throw an exception if the two objects concerned have conflicting
+ * constraints on the same degree of freedom.
*/
no_conflicts_allowed,
/**
- * In an operation
- * <code>cm1.merge(cm2)</code>, if
- * <code>cm1</code> and
- * <code>cm2</code> have
- * constraints on the same degree
- * of freedom, take the one from
- * <code>cm1</code>.
+ * In an operation <code>cm1.merge(cm2)</code>, if <code>cm1</code> and
+ * <code>cm2</code> have constraints on the same degree of freedom, take
+ * the one from <code>cm1</code>.
*/
left_object_wins,
/**
- * In an operation
- * <code>cm1.merge(cm2)</code>, if
- * <code>cm1</code> and
- * <code>cm2</code> have
- * constraints on the same degree
- * of freedom, take the one from
- * <code>cm2</code>.
+ * In an operation <code>cm1.merge(cm2)</code>, if <code>cm1</code> and
+ * <code>cm2</code> have constraints on the same degree of freedom, take
+ * the one from <code>cm2</code>.
*/
right_object_wins
};
/**
- * Constructor. The supplied IndexSet
- * defines which indices might be
- * constrained inside this
- * ConstraintMatrix. In a calculation
- * with a
- * parallel::distributed::DoFHandler one
- * should use locally_relevant_dofs. The
- * IndexSet allows the ConstraintMatrix
- * to safe memory. Otherwise internal
- * data structures for all possible
- * indices will be created.
+ * Constructor. The supplied IndexSet defines which indices might be
+ * constrained inside this ConstraintMatrix. In a calculation with a
+ * parallel::distributed::DoFHandler one should use
+ * locally_relevant_dofs. The IndexSet allows the ConstraintMatrix to safe
+ * memory. Otherwise internal data structures for all possible indices will
+ * be created.
*/
ConstraintMatrix (const IndexSet &local_constraints = IndexSet());
ConstraintMatrix (const ConstraintMatrix &constraint_matrix);
/**
- * Reinit the ConstraintMatrix object and
- * supply an IndexSet with lines that may
- * be constrained. This function is only
- * relevant in the distributed case to
- * supply a different IndexSet. Otherwise
- * this routine is equivalent to calling
- * clear(). See the constructor for
- * details.
+ * Reinit the ConstraintMatrix object and supply an IndexSet with lines that
+ * may be constrained. This function is only relevant in the distributed
+ * case to supply a different IndexSet. Otherwise this routine is equivalent
+ * to calling clear(). See the constructor for details.
*/
void reinit (const IndexSet &local_constraints = IndexSet());
/**
- * Determines if we can store a
- * constraint for the given @p
- * line_index. This routine only matters
- * in the distributed case and checks if
- * the IndexSet allows storage of this
- * line. Always returns true if not in
- * the distributed case.
+ * Determines if we can store a constraint for the given @p line_index. This
+ * routine only matters in the distributed case and checks if the IndexSet
+ * allows storage of this line. Always returns true if not in the
+ * distributed case.
*/
bool can_store_line (const size_type line_index) const;
const IndexSet & get_local_lines() const;
/**
- * This function copies the content of @p
- * constraints_in with DoFs that are
- * element of the IndexSet @p
- * filter. Elements that are not present
- * in the IndexSet are ignored. All DoFs
- * will be transformed to local index
- * space of the filter, both the
- * constrained DoFs and the other DoFs
- * these entries are constrained to. The
- * local index space of the filter is a
- * contiguous numbering of all (global)
- * DoFs that are elements in the
- * filter.
- *
- * If, for example, the filter represents
- * the range <tt>[10,20)</tt>, and the
- * constraint matrix @p constraints_in
- * includes the global indices
- * <tt>{7,13,14}</tt>, the indices
- * <tt>{3,4}</tt> are added to the
- * calling constraint matrix (since 13
- * and 14 are elements in the filter and
- * element 13 is the fourth element in
- * the index, and 14 is the fifth).
- *
- * This function provides an easy way to
- * create a ConstraintMatrix for certain
- * vector components in a vector-valued
- * problem from a full ConstraintMatrix,
- * i.e. extracting a diagonal subblock
- * from a larger ConstraintMatrix. The
- * block is specified by the IndexSet
- * argument.
+ * This function copies the content of @p constraints_in with DoFs that are
+ * element of the IndexSet @p filter. Elements that are not present in the
+ * IndexSet are ignored. All DoFs will be transformed to local index space
+ * of the filter, both the constrained DoFs and the other DoFs these entries
+ * are constrained to. The local index space of the filter is a contiguous
+ * numbering of all (global) DoFs that are elements in the filter.
+ *
+ * If, for example, the filter represents the range <tt>[10,20)</tt>, and
+ * the constraint matrix @p constraints_in includes the global indices
+ * <tt>{7,13,14}</tt>, the indices <tt>{3,4}</tt> are added to the calling
+ * constraint matrix (since 13 and 14 are elements in the filter and element
+ * 13 is the fourth element in the index, and 14 is the fifth).
+ *
+ * This function provides an easy way to create a ConstraintMatrix for
+ * certain vector components in a vector-valued problem from a full
+ * ConstraintMatrix, i.e. extracting a diagonal subblock from a larger
+ * ConstraintMatrix. The block is specified by the IndexSet argument.
*/
void add_selected_constraints (const ConstraintMatrix &constraints_in,
const IndexSet &filter);
*/
/**
- * Add a new line to the matrix. If the
- * line already exists, then the function
- * simply returns without doing anything.
+ * Add a new line to the matrix. If the line already exists, then the
+ * function simply returns without doing anything.
*/
void add_line (const size_type line);
/**
- * Call the first add_line() function for
- * every index <code>i</code> for which
- * <code>lines[i]</code> is true.
- *
- * This function essentially exists to
- * allow adding several constraints of
- * the form <i>x<sub>i</sub></i>=0 all at once, where
- * the set of indices <i>i</i> for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * Call the first add_line() function for every index <code>i</code> for
+ * which <code>lines[i]</code> is true.
+ *
+ * This function essentially exists to allow adding several constraints of
+ * the form <i>x<sub>i</sub></i>=0 all at once, where the set of indices
+ * <i>i</i> for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const std::vector<bool> &lines);
/**
- * Call the first add_line() function for
- * every index <code>i</code> that
+ * Call the first add_line() function for every index <code>i</code> that
* appears in the argument.
*
- * This function essentially exists to
- * allow adding several constraints of
- * the form <i>x<sub>i</sub></i>=0 all at once, where
- * the set of indices <i>i</i> for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * This function essentially exists to allow adding several constraints of
+ * the form <i>x<sub>i</sub></i>=0 all at once, where the set of indices
+ * <i>i</i> for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const std::set<size_type> &lines);
/**
- * Call the first add_line() function for
- * every index <code>i</code> that
+ * Call the first add_line() function for every index <code>i</code> that
* appears in the argument.
*
- * This function essentially exists to
- * allow adding several constraints of
- * the form <i>x<sub>i</sub></i>=0 all at once, where
- * the set of indices <i>i</i> for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * This function essentially exists to allow adding several constraints of
+ * the form <i>x<sub>i</sub></i>=0 all at once, where the set of indices
+ * <i>i</i> for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const IndexSet &lines);
/**
- * Add an entry to a given
- * line. The list of lines is
- * searched from the back to the
- * front, so clever programming
- * would add a new line (which is
- * pushed to the back) and
- * immediately afterwards fill
- * the entries of that line. This
- * way, no expensive searching is
- * needed.
- *
- * If an entry with the same
- * indices as the one this
- * function call denotes already
- * exists, then this function
- * simply returns provided that
- * the value of the entry is the
- * same. Thus, it does no harm to
- * enter a constraint twice.
+ * Add an entry to a given line. The list of lines is searched from the back
+ * to the front, so clever programming would add a new line (which is pushed
+ * to the back) and immediately afterwards fill the entries of that
+ * line. This way, no expensive searching is needed.
+ *
+ * If an entry with the same indices as the one this function call denotes
+ * already exists, then this function simply returns provided that the value
+ * of the entry is the same. Thus, it does no harm to enter a constraint
+ * twice.
*/
void add_entry (const size_type line,
const size_type column,
const double value);
/**
- * Add a whole series of entries,
- * denoted by pairs of column indices
- * and values, to a line of
- * constraints. This function is
- * equivalent to calling the preceding
- * function several times, but is
- * faster.
+ * Add a whole series of entries, denoted by pairs of column indices and
+ * values, to a line of constraints. This function is equivalent to calling
+ * the preceding function several times, but is faster.
*/
void add_entries (const size_type line,
const std::vector<std::pair<size_type,double> > &col_val_pairs);
/**
- * Set an imhomogeneity to the
- * constraint line <i>i</i>, according
- * to the discussion in the general
- * class description.
+ * Set an imhomogeneity to the constraint line <i>i</i>, according to the
+ * discussion in the general class description.
*
- * @note the line needs to be added with
- * one of the add_line() calls first.
+ * @note the line needs to be added with one of the add_line() calls first.
*/
void set_inhomogeneity (const size_type line,
const double value);
/**
- * Close the filling of entries. Since
- * the lines of a matrix of this type
- * are usually filled in an arbitrary
- * order and since we do not want to
- * use associative constainers to store
- * the lines, we need to sort the lines
- * and within the lines the columns
- * before usage of the matrix. This is
- * done through this function.
- *
- * Also, zero entries are discarded,
- * since they are not needed.
- *
- * After closing, no more entries are
- * accepted. If the object was already
- * closed, then this function returns
- * immediately.
- *
- * This function also resolves chains
- * of constraints. For example, degree
- * of freedom 13 may be constrained to
- * <i>u</i><sub>13</sub>=<i>u</i><sub>3</sub>/2+<i>u</i><sub>7</sub>/2 while degree of
- * freedom 7 is itself constrained as
- * <i>u</i><sub>7</sub>=<i>u</i><sub>2</sub>/2+<i>u</i><sub>4</sub>/2. Then, the
- * resolution will be that
- * <i>u</i><sub>13</sub>=<i>u</i><sub>3</sub>/2+<i>u</i><sub>2</sub>/4+<i>u</i><sub>4</sub>/4. Note,
- * however, that cycles in this graph
- * of constraints are not allowed,
- * i.e. for example <i>u</i><sub>4</sub> may not be
- * constrained, directly or indirectly,
- * to <i>u</i><sub>13</sub> again.
+ * Close the filling of entries. Since the lines of a matrix of this type
+ * are usually filled in an arbitrary order and since we do not want to use
+ * associative constainers to store the lines, we need to sort the lines and
+ * within the lines the columns before usage of the matrix. This is done
+ * through this function.
+ *
+ * Also, zero entries are discarded, since they are not needed.
+ *
+ * After closing, no more entries are accepted. If the object was already
+ * closed, then this function returns immediately.
+ *
+ * This function also resolves chains of constraints. For example, degree of
+ * freedom 13 may be constrained to $u_{13} = \frac{u_3}{2} + \frac{u_7}{2}$
+ * while degree of freedom 7 is itself constrained as $u_{7} = \frac{u_2}{2}
+ * + \frac{u_4}{2}$. Then, the resolution will be that $u_{13} =
+ * \frac{u_3}{2} + \frac{u_2}{4} + \frac{u_4}{4}$. Note, however, that
+ * cycles in this graph of constraints are not allowed, i.e. for example
+ * $u_4$ may not be constrained, directly or indirectly, to $u_{13}$ again.
*/
void close ();
/**
- * Merge the constraints represented by
- * the object given as argument into
- * the constraints represented by this
- * object. Both objects may or may not
- * be closed (by having their function
- * close() called before). If this
- * object was closed before, then it
- * will be closed afterwards as
- * well. Note, however, that if the
- * other argument is closed, then
- * merging may be significantly faster.
- *
- * Using the default value of the second
- * arguments, the constraints in each of
- * the two objects (the old one
- * represented by this object and the
- * argument) may not refer to the same
- * degree of freedom, i.e. a degree of
- * freedom that is constrained in one
- * object may not be constrained in the
- * second. If this is nevertheless the
- * case, an exception is thrown. However,
- * this behavior can be changed by
- * providing a different value for the
- * second argument.
+ * Merge the constraints represented by the object given as argument into
+ * the constraints represented by this object. Both objects may or may not
+ * be closed (by having their function close() called before). If this
+ * object was closed before, then it will be closed afterwards as
+ * well. Note, however, that if the other argument is closed, then merging
+ * may be significantly faster.
+ *
+ * Using the default value of the second arguments, the constraints in each
+ * of the two objects (the old one represented by this object and the
+ * argument) may not refer to the same degree of freedom, i.e. a degree of
+ * freedom that is constrained in one object may not be constrained in the
+ * second. If this is nevertheless the case, an exception is
+ * thrown. However, this behavior can be changed by providing a different
+ * value for the second argument.
*/
void merge (const ConstraintMatrix &other_constraints,
const MergeConflictBehavior merge_conflict_behavior = no_conflicts_allowed);
/**
- * Shift all entries of this matrix
- * down @p offset rows and over @p
- * offset columns.
+ * Shift all entries of this matrix down @p offset rows and over @p offset
+ * columns.
*
- * This function is useful if you are
- * building block matrices, where all
- * blocks are built by the same
- * DoFHandler object, i.e. the matrix
- * size is larger than the number of
- * degrees of freedom. Since several
- * matrix rows and columns correspond
- * to the same degrees of freedom,
- * you'd generate several constraint
- * objects, then shift them, and
- * finally merge() them together
- * again.
+ * This function is useful if you are building block matrices, where all
+ * blocks are built by the same DoFHandler object, i.e. the matrix size is
+ * larger than the number of degrees of freedom. Since several matrix rows
+ * and columns correspond to the same degrees of freedom, you'd generate
+ * several constraint objects, then shift them, and finally merge() them
+ * together again.
*/
void shift (const size_type offset);
/**
- * Clear all entries of this
- * matrix. Reset the flag determining
- * whether new entries are accepted or
- * not.
+ * Clear all entries of this matrix. Reset the flag determining whether new
+ * entries are accepted or not.
*
- * This function may be called also on
- * objects which are empty or already
+ * This function may be called also on objects which are empty or already
* cleared.
*/
void clear ();
*/
/**
- * Return number of constraints stored in
- * this matrix.
+ * Return number of constraints stored in this matrix.
*/
size_type n_constraints () const;
/**
- * Return whether the degree of freedom
- * with number @p index is a
+ * Return whether the degree of freedom with number @p index is a
* constrained one.
*
- * Note that if close() was called
- * before, then this function is
- * significantly faster, since then the
- * constrained degrees of freedom are
- * sorted and we can do a binary
- * search, while before close() was
- * called, we have to perform a linear
- * search through all entries.
+ * Note that if close() was called before, then this function is
+ * significantly faster, since then the constrained degrees of freedom are
+ * sorted and we can do a binary search, while before close() was called, we
+ * have to perform a linear search through all entries.
*/
bool is_constrained (const size_type index) const;
/**
- * Return whether the dof is
- * constrained, and whether it is
- * constrained to only one other degree
- * of freedom with weight one. The
- * function therefore returns whether
- * the degree of freedom would simply
- * be eliminated in favor of exactly
- * one other degree of freedom.
- *
- * The function returns @p false if
- * either the degree of freedom is not
- * constrained at all, or if it is
- * constrained to more than one other
- * degree of freedom, or if it is
- * constrained to only one degree of
- * freedom but with a weight different
- * from one.
+ * Return whether the dof is constrained, and whether it is constrained to
+ * only one other degree of freedom with weight one. The function therefore
+ * returns whether the degree of freedom would simply be eliminated in favor
+ * of exactly one other degree of freedom.
+ *
+ * The function returns @p false if either the degree of freedom is not
+ * constrained at all, or if it is constrained to more than one other degree
+ * of freedom, or if it is constrained to only one degree of freedom but
+ * with a weight different from one.
*/
bool is_identity_constrained (const size_type index) const;
/**
- * Return whether the two given degrees of freedom are linked by an
- * equality constraint that either constrains index1 to be so that
+ * Return whether the two given degrees of freedom are linked by an equality
+ * constraint that either constrains index1 to be so that
* <code>index1=index2</code> or constrains index2 so that
* <code>index2=index1</code>.
*/
const size_type index2) const;
/**
- * Return the maximum number of other
- * dofs that one dof is constrained
- * to. For example, in 2d a hanging
- * node is constrained only to its two
- * neighbors, so the returned value
- * would be 2. However, for higher
- * order elements and/or higher
- * dimensions, or other types of
- * constraints, this number is no more
- * obvious.
+ * Return the maximum number of other dofs that one dof is constrained
+ * to. For example, in 2d a hanging node is constrained only to its two
+ * neighbors, so the returned value would be 2. However, for higher order
+ * elements and/or higher dimensions, or other types of constraints, this
+ * number is no more obvious.
*
- * The name indicates that within the
- * system matrix, references to a
- * constrained node are indirected to
- * the nodes it is constrained to.
+ * The name indicates that within the system matrix, references to a
+ * constrained node are indirected to the nodes it is constrained to.
*/
size_type max_constraint_indirections () const;
/**
- * Returns <tt>true</tt> in case the
- * dof is constrained and there is a
- * non-trivial inhomogeneous valeus set
- * to the dof.
+ * Returns <tt>true</tt> in case the dof is constrained and there is a
+ * non-trivial inhomogeneous valeus set to the dof.
*/
bool is_inhomogeneously_constrained (const size_type index) const;
/**
- * Returns <tt>false</tt> if all
- * constraints in the ConstraintMatrix
- * are homogeneous ones, and
- * <tt>true</tt> if there is at least
- * one inhomogeneity.
+ * Returns <tt>false</tt> if all constraints in the ConstraintMatrix are
+ * homogeneous ones, and <tt>true</tt> if there is at least one
+ * inhomogeneity.
*/
bool has_inhomogeneities () const;
/**
- * Returns a pointer to the the vector of
- * entries if a line is constrained, and a
- * zero pointer in case the dof is not
- * constrained.
+ * Returns a pointer to the the vector of entries if a line is constrained,
+ * and a zero pointer in case the dof is not constrained.
*/
const std::vector<std::pair<size_type,double> > *
get_constraint_entries (const size_type line) const;
/**
- * Returns the value of the inhomogeneity
- * stored in the constrained dof @p
- * line. Unconstrained dofs also return a
- * zero value.
+ * Returns the value of the inhomogeneity stored in the constrained dof @p
+ * line. Unconstrained dofs also return a zero value.
*/
double get_inhomogeneity (const size_type line) const;
/**
- * Print the constraint lines. Mainly
- * for debugging purposes.
+ * Print the constraint lines. Mainly for debugging purposes.
*
- * This function writes out all entries
- * in the constraint matrix lines with
- * their value in the form <tt>row col
- * : value</tt>. Unconstrained lines
- * containing only one identity entry
- * are not stored in this object and
- * are not printed.
+ * This function writes out all entries in the constraint matrix lines with
+ * their value in the form <tt>row col : value</tt>. Unconstrained lines
+ * containing only one identity entry are not stored in this object and are
+ * not printed.
*/
void print (std::ostream &) const;
/**
- * Write the graph of constraints in
- * 'dot' format. 'dot' is a program
- * that can take a list of nodes and
- * produce a graphical representation
- * of the graph of constrained degrees
- * of freedom and the degrees of
- * freedom they are constrained to.
+ * Write the graph of constraints in 'dot' format. 'dot' is a program that
+ * can take a list of nodes and produce a graphical representation of the
+ * graph of constrained degrees of freedom and the degrees of freedom they
+ * are constrained to.
*
- * The output of this function can be
- * used as input to the 'dot' program
- * that can convert the graph into a
- * graphical representation in
- * postscript, png, xfig, and a number
- * of other formats.
+ * The output of this function can be used as input to the 'dot' program
+ * that can convert the graph into a graphical representation in postscript,
+ * png, xfig, and a number of other formats.
*
- * This function exists mostly for
- * debugging purposes.
+ * This function exists mostly for debugging purposes.
*/
void write_dot (std::ostream &) const;
/**
- * Determine an estimate for the memory
- * consumption (in bytes) of this
+ * Determine an estimate for the memory consumption (in bytes) of this
* object.
*/
std::size_t memory_consumption () const;
/**
* Add the constraint indices associated to the indices in the given vector.
- * After a call to this function, the indices vector contains the
- * initial elements and all the associated constrained indices. This
- * function sorts the elements and suppresses duplicates.
+ * After a call to this function, the indices vector contains the initial
+ * elements and all the associated constrained indices. This function sorts
+ * the elements and suppresses duplicates.
*/
void resolve_indices(std::vector<types::global_dof_index> &indices) const;
*/
/**
- * Condense a given sparsity
- * pattern. This function assumes the
- * uncondensed matrix struct to be
- * compressed and the one to be filled
- * to be empty. The condensed structure
- * is compressed afterwards.
+ * Condense a given sparsity pattern. This function assumes the uncondensed
+ * matrix struct to be compressed and the one to be filled to be empty. The
+ * condensed structure is compressed afterwards.
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
- * @note The hanging nodes are
- * completely eliminated from the
- * linear system referring to
- * <tt>condensed</tt>. Therefore, the
- * dimension of <tt>condensed</tt> is
- * the dimension of
- * <tt>uncondensed</tt> minus the
- * number of constrained degrees of
- * freedom.
+ * @note The hanging nodes are completely eliminated from the linear system
+ * referring to <tt>condensed</tt>. Therefore, the dimension of
+ * <tt>condensed</tt> is the dimension of <tt>uncondensed</tt> minus the
+ * number of constrained degrees of freedom.
*/
void condense (const SparsityPattern &uncondensed,
SparsityPattern &condensed) const;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses the matrix struct
- * 'in-place'. It does not remove
- * nonzero entries from the matrix but
- * adds those needed for the process of
- * distribution of the constrained
- * degrees of freedom.
+ * This function does much the same as the above one, except that it
+ * condenses the matrix struct 'in-place'. It does not remove nonzero
+ * entries from the matrix but adds those needed for the process of
+ * distribution of the constrained degrees of freedom.
*
- * Since this function adds new nonzero
- * entries to the sparsity pattern, the
- * argument must not be
- * compressed. However the constraint
- * matrix must be closed. The matrix
- * struct is compressed at the end of
- * the function.
+ * Since this function adds new nonzero entries to the sparsity pattern, the
+ * argument must not be compressed. However the constraint matrix must be
+ * closed. The matrix struct is compressed at the end of the function.
*/
void condense (SparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square block sparsity
- * patterns.
+ * Same function as above, but condenses square block sparsity patterns.
*/
void condense (BlockSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*
- * Given the data structure used by
- * CompressedSparsityPattern, this
- * function becomes quadratic in the
- * number of degrees of freedom for
- * large problems and can dominate
- * setting up linear systems when
- * several hundred thousand or millions
- * of unknowns are involved and for
- * problems with many nonzero elements
- * per row (for example for
- * vector-valued problems or hp finite
- * elements). In this case, it is
- * advisable to use the
- * CompressedSetSparsityPattern class
- * instead, see for example @ref
- * step_27 "step-27", or to use the
- * CompressedSimpleSparsityPattern
- * class, see for example @ref step_31
- * "step-31".
+ * Given the data structure used by CompressedSparsityPattern, this function
+ * becomes quadratic in the number of degrees of freedom for large problems
+ * and can dominate setting up linear systems when several hundred thousand
+ * or millions of unknowns are involved and for problems with many nonzero
+ * elements per row (for example for vector-valued problems or hp finite
+ * elements). In this case, it is advisable to use the
+ * CompressedSetSparsityPattern class instead, see for example @ref step_27
+ * "step-27", or to use the CompressedSimpleSparsityPattern class, see for
+ * example @ref step_31 "step-31".
*/
void condense (CompressedSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses compressed sparsity
- * patterns, which are based on the
- * std::set container.
+ * Same function as above, but condenses compressed sparsity patterns, which
+ * are based on the std::set container.
*/
void condense (CompressedSetSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses compressed sparsity
- * patterns, which are based on the
- * ''simple'' aproach.
+ * Same function as above, but condenses compressed sparsity patterns, which
+ * are based on the ''simple'' aproach.
*/
void condense (CompressedSimpleSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*
- * Given the data structure used by
- * BlockCompressedSparsityPattern, this
- * function becomes quadratic in the
- * number of degrees of freedom for
- * large problems and can dominate
- * setting up linear systems when
- * several hundred thousand or millions
- * of unknowns are involved and for
- * problems with many nonzero elements
- * per row (for example for
- * vector-valued problems or hp finite
- * elements). In this case, it is
- * advisable to use the
- * BlockCompressedSetSparsityPattern
- * class instead, see for example @ref
- * step_27 "step-27" and @ref step_31
- * "step-31".
+ * Given the data structure used by BlockCompressedSparsityPattern, this
+ * function becomes quadratic in the number of degrees of freedom for large
+ * problems and can dominate setting up linear systems when several hundred
+ * thousand or millions of unknowns are involved and for problems with many
+ * nonzero elements per row (for example for vector-valued problems or hp
+ * finite elements). In this case, it is advisable to use the
+ * BlockCompressedSetSparsityPattern class instead, see for example @ref
+ * step_27 "step-27" and @ref step_31 "step-31".
*/
void condense (BlockCompressedSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*/
void condense (BlockCompressedSetSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*/
void condense (BlockCompressedSimpleSparsityPattern &sparsity) const;
/**
- * Condense a given matrix. The
- * associated matrix struct should be
- * condensed and compressed. It is the
- * user's responsibility to guarantee
- * that all entries in the @p condensed
- * matrix be zero!
+ * Condense a given matrix. The associated matrix struct should be condensed
+ * and compressed. It is the user's responsibility to guarantee that all
+ * entries in the @p condensed matrix be zero!
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
SparseMatrix<number> &condensed) const DEAL_II_DEPRECATED;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses the matrix 'in-place'. See
- * the general documentation of this
+ * This function does much the same as the above one, except that it
+ * condenses the matrix 'in-place'. See the general documentation of this
* class for more detailed information.
*/
template<typename number>
void condense (SparseMatrix<number> &matrix) const;
/**
- * Same function as above, but
- * condenses square block sparse
- * matrices.
+ * Same function as above, but condenses square block sparse matrices.
*/
template <typename number>
void condense (BlockSparseMatrix<number> &matrix) const;
/**
- * Condense the given vector @p
- * uncondensed into @p condensed. It is
- * the user's responsibility to
- * guarantee that all entries of @p
- * condensed be zero. Note that this
- * function does not take any
- * inhomogeneity into account and
- * throws an exception in case there
- * are any inhomogeneities. Use
- * the function using both a matrix and
- * vector for that case.
- *
- * The @p VectorType may be a
- * Vector<float>, Vector<double>,
- * BlockVector<tt><...></tt>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface.
+ * Condense the given vector @p uncondensed into @p condensed. It is the
+ * user's responsibility to guarantee that all entries of @p condensed be
+ * zero. Note that this function does not take any inhomogeneity into
+ * account and throws an exception in case there are any
+ * inhomogeneities. Use the function using both a matrix and vector for that
+ * case.
+ *
+ * The @p VectorType may be a Vector<float>, Vector<double>,
+ * BlockVector<tt><...></tt>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
VectorType &condensed) const DEAL_II_DEPRECATED;
/**
- * Condense the given vector
- * in-place. The @p VectorType may be a
- * Vector<float>, Vector<double>,
- * BlockVector<tt><...></tt>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface. Note that this function
- * does not take any inhomogeneity into
- * account and throws an exception in
- * case there are any
- * inhomogeneities. Use the function
- * using both a matrix and vector for
- * that case.
+ * Condense the given vector in-place. The @p VectorType may be a
+ * Vector<float>, Vector<double>, BlockVector<tt><...></tt>, a PETSc or
+ * Trilinos vector wrapper class, or any other type having the same
+ * interface. Note that this function does not take any inhomogeneity into
+ * account and throws an exception in case there are any
+ * inhomogeneities. Use the function using both a matrix and vector for that
+ * case.
*/
template <class VectorType>
void condense (VectorType &vec) const;
/**
- * Condense a given matrix and a given
- * vector. The associated matrix struct
- * should be condensed and
- * compressed. It is the user's
- * responsibility to guarantee that all
- * entries in the @p condensed matrix
- * and vector be zero! This function is
- * the appropriate choice for applying
- * inhomogeneous constraints.
+ * Condense a given matrix and a given vector. The associated matrix struct
+ * should be condensed and compressed. It is the user's responsibility to
+ * guarantee that all entries in the @p condensed matrix and vector be zero!
+ * This function is the appropriate choice for applying inhomogeneous
+ * constraints.
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
VectorType &condensed_vector) const DEAL_II_DEPRECATED;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses matrix and vector
- * 'in-place'. See the general
- * documentation of this class for more
- * detailed information.
+ * This function does much the same as the above one, except that it
+ * condenses matrix and vector 'in-place'. See the general documentation of
+ * this class for more detailed information.
*/
template<typename number, class VectorType>
void condense (SparseMatrix<number> &matrix,
VectorType &vector) const;
/**
- * Same function as above, but
- * condenses square block sparse
- * matrices and vectors.
+ * Same function as above, but condenses square block sparse matrices and
+ * vectors.
*/
template <typename number, class BlockVectorType>
void condense (BlockSparseMatrix<number> &matrix,
BlockVectorType &vector) const;
/**
- * Sets the values of all constrained
- * DoFs in a vector to zero.
- * The @p VectorType may be a
- * Vector<float>, Vector<double>,
- * BlockVector<tt><...></tt>, a
- * PETSc or Trilinos vector
- * wrapper class, or any other
- * type having the same
- * interface.
+ * Sets the values of all constrained DoFs in a vector to zero. The @p
+ * VectorType may be a Vector<float>, Vector<double>,
+ * BlockVector<tt><...></tt>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*/
template <class VectorType>
void set_zero (VectorType &vec) const;
*/
/**
- * This function takes a vector of
- * local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_vector and @p
- * local_dof_indices have the same
- * number of elements, this function is
- * happy with whatever it is
- * given.
- *
- * In contrast to the similar function
- * in the DoFAccessor class, this
- * function also takes care of
- * constraints, i.e. if one of the
- * elements of @p local_dof_indices
- * belongs to a constrained node, then
- * rather than writing the
- * corresponding element of @p
- * local_vector into @p global_vector,
- * the element is distributed to the
- * entries in the global vector to
- * which this particular degree of
- * freedom is constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to the
- * global object, one saves the call to
- * the condense function after the
- * vectors and matrices are fully
- * assembled. On the other hand, by
- * consequence, the function does not
- * only write into the entries enumerated
- * by the @p local_dof_indices array, but
- * also (possibly) others as necessary.
- *
- * Note that this function will apply all
- * constraints as if they were
- * homogeneous. For correctly setting
- * inhomogeneous constraints, use the
- * similar function with a matrix
- * argument or the function with both
- * matrix and vector arguments.
- *
- * @note This function is not
- * thread-safe, so you will need to make
- * sure that only one process at a time
- * calls this function.
+ * This function takes a vector of local contributions (@p local_vector)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_vector and @p
+ * local_dof_indices have the same number of elements, this function is
+ * happy with whatever it is given.
+ *
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_vector into @p
+ * global_vector, the element is distributed to the entries in the global
+ * vector to which this particular degree of freedom is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. On the other hand, by
+ * consequence, the function does not only write into the entries enumerated
+ * by the @p local_dof_indices array, but also (possibly) others as
+ * necessary.
+ *
+ * Note that this function will apply all constraints as if they were
+ * homogeneous. For correctly setting inhomogeneous constraints, use the
+ * similar function with a matrix argument or the function with both matrix
+ * and vector arguments.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <class InVector, class OutVector>
void
OutVector &global_vector) const;
/**
- * This function takes a vector of
- * local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_vector and @p
- * local_dof_indices have the same
- * number of elements, this function is
- * happy with whatever it is
- * given.
- *
- * In contrast to the similar function in
- * the DoFAccessor class, this function
- * also takes care of constraints,
- * i.e. if one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p local_vector into @p global_vector,
- * the element is distributed to the
- * entries in the global vector to which
- * this particular degree of freedom is
- * constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to the
- * global object, one saves the call to
- * the condense function after the
- * vectors and matrices are fully
- * assembled. On the other hand, by
- * consequence, the function does not
- * only write into the entries enumerated
- * by the @p local_dof_indices array, but
- * also (possibly) others as
- * necessary. This includes writing into
- * diagonal elements of the matrix if the
- * corresponding degree of freedom is
- * constrained.
+ * This function takes a vector of local contributions (@p local_vector)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_vector and @p
+ * local_dof_indices have the same number of elements, this function is
+ * happy with whatever it is given.
*
- * The fourth argument
- * <tt>local_matrix</tt> is intended to
- * be used in case one wants to apply
- * inhomogeneous constraints on the
- * vector only. Such a situation could be
- * where one wants to assemble of a right
- * hand side vector on a problem with
- * inhomogeneous constraints, but the
- * global matrix has been assembled
- * previously. A typical example of this
- * is a time stepping algorithm where the
- * stiffness matrix is assembled once,
- * and the right hand side updated every
- * time step. Note that, however, the
- * entries in the columns of the local
- * matrix have to be exactly the same as
- * those that have been written into the
- * global matrix. Otherwise, this
- * function will not be able to correctly
- * handle inhomogeneities.
- *
- * @note This function is not
- * thread-safe, so you will need to make
- * sure that only one process at a time
- * calls this function.
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_vector into @p
+ * global_vector, the element is distributed to the entries in the global
+ * vector to which this particular degree of freedom is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. On the other hand, by
+ * consequence, the function does not only write into the entries enumerated
+ * by the @p local_dof_indices array, but also (possibly) others as
+ * necessary. This includes writing into diagonal elements of the matrix if
+ * the corresponding degree of freedom is constrained.
+ *
+ * The fourth argument <tt>local_matrix</tt> is intended to be used in case
+ * one wants to apply inhomogeneous constraints on the vector only. Such a
+ * situation could be where one wants to assemble of a right hand side
+ * vector on a problem with inhomogeneous constraints, but the global matrix
+ * has been assembled previously. A typical example of this is a time
+ * stepping algorithm where the stiffness matrix is assembled once, and the
+ * right hand side updated every time step. Note that, however, the entries
+ * in the columns of the local matrix have to be exactly the same as those
+ * that have been written into the global matrix. Otherwise, this function
+ * will not be able to correctly handle inhomogeneities.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <typename VectorType>
void
const FullMatrix<double> &local_matrix) const;
/**
- * Enter a single value into a
- * result vector, obeying constraints.
+ * Enter a single value into a result vector, obeying constraints.
*/
template <class VectorType>
void
VectorType &global_vector) const;
/**
- * This function takes a pointer to a
- * vector of local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as the
- * entries in @p local_dof_indices
- * indicate reasonable global vector
- * entries, this function is happy with
- * whatever it is given.
- *
- * If one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p local_vector into @p
- * global_vector, the element is
- * distributed to the entries in the
- * global vector to which this
- * particular degree of freedom is
- * constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to
- * the global object, one saves the
- * call to the condense function after
- * the vectors and matrices are fully
- * assembled. Note that this function
- * completely ignores inhomogeneous
- * constraints.
- *
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * This function takes a pointer to a vector of local contributions (@p
+ * local_vector) corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as the entries in @p
+ * local_dof_indices indicate reasonable global vector entries, this
+ * function is happy with whatever it is given.
+ *
+ * If one of the elements of @p local_dof_indices belongs to a constrained
+ * node, then rather than writing the corresponding element of @p
+ * local_vector into @p global_vector, the element is distributed to the
+ * entries in the global vector to which this particular degree of freedom
+ * is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. Note that this function
+ * completely ignores inhomogeneous constraints.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <typename ForwardIteratorVec, typename ForwardIteratorInd,
class VectorType>
VectorType &global_vector) const;
/**
- * This function takes a matrix of
- * local contributions (@p
- * local_matrix) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global matrix. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_matrix and @p
- * local_dof_indices have the same
- * number of elements, this function is
+ * This function takes a matrix of local contributions (@p local_matrix)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global matrix. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_matrix and @p
+ * local_dof_indices have the same number of elements, this function is
* happy with whatever it is given.
*
- * In contrast to the similar function
- * in the DoFAccessor class, this
- * function also takes care of
- * constraints, i.e. if one of the
- * elements of @p local_dof_indices
- * belongs to a constrained node, then
- * rather than writing the
- * corresponding element of @p
- * local_matrix into @p global_matrix,
- * the element is distributed to the
- * entries in the global matrix to
- * which this particular degree of
- * freedom is constrained.
- *
- * With this scheme, we never write
- * into rows or columns of constrained
- * degrees of freedom. In order to make
- * sure that the resulting matrix can
- * still be inverted, we need to do
- * something with the diagonal elements
- * corresponding to constrained
- * nodes. Thus, if a degree of freedom
- * in @p local_dof_indices is
- * constrained, we distribute the
- * corresponding entries in the matrix,
- * but also add the absolute value of
- * the diagonal entry of the local
- * matrix to the corresponding entry in
- * the global matrix. Since the exact
- * value of the diagonal element is not
- * important (the value of the
- * respective degree of freedom will be
- * overwritten by the distribute() call
- * later on anyway), this guarantees
- * that the diagonal entry is always
- * non-zero, positive, and of the same
- * order of magnitude as the other
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_matrix into @p
+ * global_matrix, the element is distributed to the entries in the global
+ * matrix to which this particular degree of freedom is constrained.
+ *
+ * With this scheme, we never write into rows or columns of constrained
+ * degrees of freedom. In order to make sure that the resulting matrix can
+ * still be inverted, we need to do something with the diagonal elements
+ * corresponding to constrained nodes. Thus, if a degree of freedom in @p
+ * local_dof_indices is constrained, we distribute the corresponding entries
+ * in the matrix, but also add the absolute value of the diagonal entry of
+ * the local matrix to the corresponding entry in the global matrix. Since
+ * the exact value of the diagonal element is not important (the value of
+ * the respective degree of freedom will be overwritten by the distribute()
+ * call later on anyway), this guarantees that the diagonal entry is always
+ * non-zero, positive, and of the same order of magnitude as the other
* entries of the matrix.
*
- * Thus, by using this function to
- * distribute local contributions to
- * the global object, one saves the
- * call to the condense function after
- * the vectors and matrices are fully
- * assembled.
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled.
*
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global matrix allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <typename MatrixType>
void
MatrixType &global_matrix) const;
/**
- * Does the same as the function
- * above but can treat non
- * quadratic matrices.
+ * Does the same as the function above but can treat non quadratic matrices.
*/
template <typename MatrixType>
void
MatrixType &global_matrix) const;
/**
- * This function simultaneously
- * writes elements into matrix
- * and vector, according to the
- * constraints specified by the
- * calling ConstraintMatrix. This
- * function can correctly handle
- * inhomogeneous constraints as
- * well. For the parameter
- * use_inhomogeneities_for_rhs
- * see the documentation in @ref
- * constraints module.
+ * This function simultaneously writes elements into matrix and vector,
+ * according to the constraints specified by the calling
+ * ConstraintMatrix. This function can correctly handle inhomogeneous
+ * constraints as well. For the parameter use_inhomogeneities_for_rhs see
+ * the documentation in @ref constraints module.
*
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global matrix and vector allow
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <typename MatrixType, typename VectorType>
void
bool use_inhomogeneities_for_rhs = false) const;
/**
- * Do a similar operation as the
- * distribute_local_to_global() function
- * that distributes writing entries into
- * a matrix for constrained degrees of
- * freedom, except that here we don't
- * write into a matrix but only allocate
+ * Do a similar operation as the distribute_local_to_global() function that
+ * distributes writing entries into a matrix for constrained degrees of
+ * freedom, except that here we don't write into a matrix but only allocate
* sparsity pattern entries.
*
- * As explained in the
- * @ref hp_paper "hp paper"
- * and in step-27,
- * first allocating a sparsity pattern
- * and later coming back and allocating
- * additional entries for those matrix
- * entries that will be written to due to
- * the elimination of constrained degrees
- * of freedom (using
- * ConstraintMatrix::condense() ), can be
- * a very expensive procedure. It is
- * cheaper to allocate these entries
- * right away without having to do a
- * second pass over the sparsity pattern
- * object. This function does exactly
+ * As explained in the @ref hp_paper "hp paper" and in step-27, first
+ * allocating a sparsity pattern and later coming back and allocating
+ * additional entries for those matrix entries that will be written to due
+ * to the elimination of constrained degrees of freedom (using
+ * ConstraintMatrix::condense() ), can be a very expensive procedure. It is
+ * cheaper to allocate these entries right away without having to do a
+ * second pass over the sparsity pattern object. This function does exactly
* that.
*
- * Because the function only allocates
- * entries in a sparsity pattern, all it
- * needs to know are the degrees of
- * freedom that couple to each
- * other. Unlike the previous function,
- * no actual values are written, so the
- * second input argument is not necessary
- * here.
- *
- * The third argument to this function,
- * keep_constrained_entries determines
- * whether the function shall allocate
- * entries in the sparsity pattern at
- * all for entries that will later be
- * set to zero upon condensation of the
- * matrix. These entries are necessary
- * if the matrix is built
- * unconstrained, and only later
- * condensed. They are not necessary if
- * the matrix is built using the
- * distribute_local_to_global()
- * function of this class which
- * distributes entries right away when
- * copying a local matrix into a global
- * object. The default of this argument
- * is true, meaning to allocate the few
- * entries that may later be set to
- * zero.
- *
- * By default, the function adds
- * entries for all pairs of indices
- * given in the first argument to the
- * sparsity pattern (unless
- * keep_constrained_entries is
- * false). However, sometimes one would
- * like to only add a subset of all of
- * these pairs. In that case, the last
- * argument can be used which specifies
- * a boolean mask which of the pairs of
- * indices should be considered. If the
- * mask is false for a pair of indices,
- * then no entry will be added to the
- * sparsity pattern for this pair,
- * irrespective of whether one or both
- * of the indices correspond to
- * constrained degrees of freedom.
- *
- * This function is not typically called
- * from user code, but is used in the
- * DoFTools::make_sparsity_pattern()
- * function when passed a constraint
+ * Because the function only allocates entries in a sparsity pattern, all it
+ * needs to know are the degrees of freedom that couple to each
+ * other. Unlike the previous function, no actual values are written, so the
+ * second input argument is not necessary here.
+ *
+ * The third argument to this function, keep_constrained_entries determines
+ * whether the function shall allocate entries in the sparsity pattern at
+ * all for entries that will later be set to zero upon condensation of the
+ * matrix. These entries are necessary if the matrix is built unconstrained,
+ * and only later condensed. They are not necessary if the matrix is built
+ * using the distribute_local_to_global() function of this class which
+ * distributes entries right away when copying a local matrix into a global
+ * object. The default of this argument is true, meaning to allocate the few
+ * entries that may later be set to zero.
+ *
+ * By default, the function adds entries for all pairs of indices given in
+ * the first argument to the sparsity pattern (unless
+ * keep_constrained_entries is false). However, sometimes one would like to
+ * only add a subset of all of these pairs. In that case, the last argument
+ * can be used which specifies a boolean mask which of the pairs of indices
+ * should be considered. If the mask is false for a pair of indices, then no
+ * entry will be added to the sparsity pattern for this pair, irrespective
+ * of whether one or both of the indices correspond to constrained degrees
+ * of freedom.
+ *
+ * This function is not typically called from user code, but is used in the
+ * DoFTools::make_sparsity_pattern() function when passed a constraint
* matrix object.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global sparsity pattern allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template <typename SparsityType>
void
add_entries_local_to_global (const std::vector<size_type> &local_dof_indices,
SparsityType &sparsity_pattern,
const bool keep_constrained_entries = true,
- const Table<2,bool> &dof_mask = default_empty_table) const;
+ const Table<2,bool> &dof_mask = default_empty_table) const;
/**
- * Similar to the other function,
- * but for non-quadratic sparsity
- * patterns.
+ * Similar to the other function, but for non-quadratic sparsity patterns.
*/
-
template <typename SparsityType>
void
add_entries_local_to_global (const std::vector<size_type> &row_indices,
const Table<2,bool> &dof_mask = default_empty_table) const;
/**
- * This function imports values from a
- * global vector (@p global_vector) by
- * applying the constraints to a vector
- * of local values, expressed in
- * iterator format. In most cases, the
- * local values will be identified by
- * the local dof values on a
- * cell. However, as long as the
- * entries in @p local_dof_indices
- * indicate reasonable global vector
- * entries, this function is happy with
- * whatever it is given.
- *
- * If one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p global_vector into @p
- * local_vector, the constraints are
- * resolved as the respective
- * distribute function does, i.e., the
- * local entry is constructed from the
- * global entries to which this
- * particular degree of freedom is
+ * This function imports values from a global vector (@p global_vector) by
+ * applying the constraints to a vector of local values, expressed in
+ * iterator format. In most cases, the local values will be identified by
+ * the local dof values on a cell. However, as long as the entries in @p
+ * local_dof_indices indicate reasonable global vector entries, this
+ * function is happy with whatever it is given.
+ *
+ * If one of the elements of @p local_dof_indices belongs to a constrained
+ * node, then rather than writing the corresponding element of @p
+ * global_vector into @p local_vector, the constraints are resolved as the
+ * respective distribute function does, i.e., the local entry is constructed
+ * from the global entries to which this particular degree of freedom is
* constrained.
*
- * In contrast to the similar function
- * get_dof_values in the DoFAccessor
- * class, this function does not need
- * the constrained values to be
- * correctly set (i.e., distribute to
- * be called).
+ * In contrast to the similar function get_dof_values in the DoFAccessor
+ * class, this function does not need the constrained values to be correctly
+ * set (i.e., distribute to be called).
*/
template <typename ForwardIteratorVec, typename ForwardIteratorInd,
class VectorType>
*/
/**
- * Re-distribute the elements of the
- * vector @p condensed to @p
- * uncondensed. It is the user's
- * responsibility to guarantee that all
+ * Re-distribute the elements of the vector @p condensed to @p
+ * uncondensed. It is the user's responsibility to guarantee that all
* entries of @p uncondensed be zero!
*
- * This function undoes the action of
- * @p condense somehow, but it should
- * be noted that it is not the inverse
- * of @p condense.
+ * This function undoes the action of @p condense somehow, but it should be
+ * noted that it is not the inverse of @p condense.
*
- * The @p VectorType may be a
- * Vector<float>, Vector<double>,
- * BlockVector<tt><...></tt>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface.
+ * The @p VectorType may be a Vector<float>, Vector<double>,
+ * BlockVector<tt><...></tt>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*/
template <class VectorType>
void distribute (const VectorType &condensed,
VectorType &uncondensed) const;
/**
- * Re-distribute the elements of the
- * vector in-place. The @p VectorType
- * may be a Vector<float>,
- * Vector<double>,
- * BlockVector<tt><...></tt>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
+ * Re-distribute the elements of the vector in-place. The @p VectorType may
+ * be a Vector<float>, Vector<double>, BlockVector<tt><...></tt>, a PETSc or
+ * Trilinos vector wrapper class, or any other type having the same
* interface.
*
- * Note that if called with a
- * TrilinosWrappers::MPI::Vector it may
- * not contain ghost elements.
+ * Note that if called with a TrilinosWrappers::MPI::Vector it may not
+ * contain ghost elements.
*/
template <class VectorType>
void distribute (VectorType &vec) const;
private:
/**
- * This class represents one line of a
- * constraint matrix.
+ * This class represents one line of a constraint matrix.
*/
struct ConstraintLine
{
/**
- * A data type in which we store the list
- * of entries that make up the homogenous
- * part of a constraint.
+ * A data type in which we store the list of entries that make up the
+ * homogenous part of a constraint.
*/
typedef std::vector<std::pair<size_type,double> > Entries;
/**
- * Number of this line. Since only
- * very few lines are stored, we
- * can not assume a specific order
- * and have to store the line
- * number explicitly.
+ * Number of this line. Since only very few lines are stored, we can not
+ * assume a specific order and have to store the line number explicitly.
*/
size_type line;
/**
- * Row numbers and values of the
- * entries in this line.
+ * Row numbers and values of the entries in this line.
*
- * For the reason why we use a
- * vector instead of a map and the
- * consequences thereof, the same
- * applies as what is said for
+ * For the reason why we use a vector instead of a map and the
+ * consequences thereof, the same applies as what is said for
* ConstraintMatrix::lines.
*/
Entries entries;
double inhomogeneity;
/**
- * This operator is a bit weird and
- * unintuitive: it compares the
- * line numbers of two lines. We
- * need this to sort the lines; in
- * fact we could do this using a
- * comparison predicate. However,
- * this way, it is easier, albeit
- * unintuitive since two lines
- * really have no god-given order
+ * This operator is a bit weird and unintuitive: it compares the line
+ * numbers of two lines. We need this to sort the lines; in fact we could
+ * do this using a comparison predicate. However, this way, it is easier,
+ * albeit unintuitive since two lines really have no god-given order
* relation.
*/
bool operator < (const ConstraintLine &) const;
/**
- * This operator is likewise weird:
- * it checks whether the line
- * indices of the two operands are
- * equal, irrespective of the fact
- * that the contents of the line
- * may be different.
+ * This operator is likewise weird: it checks whether the line indices of
+ * the two operands are equal, irrespective of the fact that the contents
+ * of the line may be different.
*/
bool operator == (const ConstraintLine &) 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;
};
/**
- * Store the lines of the matrix.
- * Entries are usually appended in an
- * arbitrary order and insertion into a
- * vector is done best at the end, so
- * the order is unspecified after all
- * entries are inserted. Sorting of the
- * entries takes place when calling the
- * <tt>close()</tt> function.
+ * Store the lines of the matrix. Entries are usually appended in an
+ * arbitrary order and insertion into a vector is done best at the end, so
+ * the order is unspecified after all entries are inserted. Sorting of the
+ * entries takes place when calling the <tt>close()</tt> function.
*
- * We could, instead of using a vector,
- * use an associative array, like a map
- * to store the lines. This, however,
- * would mean a much more fractioned
- * heap since it allocates many small
- * objects, and would additionally make
- * usage of this matrix much slower.
+ * We could, instead of using a vector, use an associative array, like a map
+ * to store the lines. This, however, would mean a much more fractioned heap
+ * since it allocates many small objects, and would additionally make usage
+ * of this matrix much slower.
*/
std::vector<ConstraintLine> lines;
/**
- * A list of size_type that
- * contains the position of the
- * ConstraintLine of a constrained degree
- * of freedom, or
- * numbers::invalid_size_type if the
- * degree of freedom is not
- * constrained. The
- * numbers::invalid_size_type
- * return value returns thus whether
- * there is a constraint line for a given
- * degree of freedom index. Note that
- * this class has no notion of how many
- * degrees of freedom there really are,
- * so if we check whether there is a
- * constraint line for a given degree of
- * freedom, then this vector may actually
- * be shorter than the index of the DoF
- * we check for.
- *
- * This field exists since when adding a
- * new constraint line we have to figure
- * out whether it already
- * exists. Previously, we would simply
- * walk the unsorted list of constraint
- * lines until we either hit the end or
- * found it. This algorithm is O(N) if N
- * is the number of constraints, which
- * makes it O(N^2) when inserting all
- * constraints. For large problems with
- * many constraints, this could easily
- * take 5-10 per cent of the total run
- * time. With this field, we can save
- * this time since we find any constraint
- * in O(1) time or get to know that it a
- * certain degree of freedom is not
+ * A list of size_type that contains the position of the ConstraintLine of a
+ * constrained degree of freedom, or numbers::invalid_size_type if the
+ * degree of freedom is not constrained. The numbers::invalid_size_type
+ * return value returns thus whether there is a constraint line for a given
+ * degree of freedom index. Note that this class has no notion of how many
+ * degrees of freedom there really are, so if we check whether there is a
+ * constraint line for a given degree of freedom, then this vector may
+ * actually be shorter than the index of the DoF we check for.
+ *
+ * This field exists since when adding a new constraint line we have to
+ * figure out whether it already exists. Previously, we would simply walk
+ * the unsorted list of constraint lines until we either hit the end or
+ * found it. This algorithm is O(N) if N is the number of constraints, which
+ * makes it O(N^2) when inserting all constraints. For large problems with
+ * many constraints, this could easily take 5-10 per cent of the total run
+ * time. With this field, we can save this time since we find any constraint
+ * in O(1) time or get to know that it a certain degree of freedom is not
* constrained.
*
- * To make things worse, traversing the
- * list of existing constraints requires
- * reads from many different places in
- * memory. Thus, in large 3d
- * applications, the add_line() function
- * showed up very prominently in the
- * overall compute time, mainly because
- * it generated a lot of cache
- * misses. This should also be fixed by
- * using the O(1) algorithm to access the
- * fields of this array.
- *
- * The field is useful in a number of
- * other contexts as well, e.g. when one
- * needs random access to the constraints
- * as in all the functions that apply
- * constraints on the fly while add cell
- * contributions into vectors and
+ * To make things worse, traversing the list of existing constraints
+ * requires reads from many different places in memory. Thus, in large 3d
+ * applications, the add_line() function showed up very prominently in the
+ * overall compute time, mainly because it generated a lot of cache
+ * misses. This should also be fixed by using the O(1) algorithm to access
+ * the fields of this array.
+ *
+ * The field is useful in a number of other contexts as well, e.g. when one
+ * needs random access to the constraints as in all the functions that apply
+ * constraints on the fly while add cell contributions into vectors and
* matrices.
*/
std::vector<size_type> lines_cache;
/**
- * This IndexSet is used to limit the
- * lines to save in the ContraintMatrix
- * to a subset. This is necessary,
- * because the lines_cache vector would
- * become too big in a distributed
- * calculation.
+ * This IndexSet is used to limit the lines to save in the ConstraintMatrix
+ * to a subset. This is necessary, because the lines_cache vector would
+ * become too big in a distributed calculation.
*/
IndexSet local_lines;
/**
- * Store whether the arrays are sorted.
- * If so, no new entries can be added.
+ * Store whether the arrays are sorted. If so, no new entries can be added.
*/
bool sorted;
/**
- * Internal function to calculate the
- * index of line @p line in the vector
+ * Scratch data that is used during calls to distribute_local_to_global and
+ * add_entries_local_to_global. In order to avoid frequent memory
+ * allocation, we keep the data alive from one call to the next.
+ */
+ struct ScratchData
+ {
+ /**
+ * Constructor, does nothing.
+ */
+ ScratchData () :
+ in_use (false)
+ {}
+
+ /**
+ * Copy constructor, does nothing
+ */
+ ScratchData (const ScratchData &) :
+ in_use (false)
+ {}
+
+ /**
+ * Stores whether the data is currently in use.
+ */
+ bool in_use;
+
+ /**
+ * Temporary array for column indices
+ */
+ std::vector<size_type> columns;
+
+ /**
+ * Temporary array for column values
+ */
+ std::vector<double> values;
+
+ /**
+ * Temporary array for block start indices
+ */
+ std::vector<size_type> block_starts;
+
+ /**
+ * Temporary array for vector indices
+ */
+ std::vector<size_type> vector_indices;
+
+ /**
+ * Data array for reorder row/column indices. Use a shared ptr to
+ * global_rows to avoid defining in the .h file
+ */
+ std_cxx1x::shared_ptr<internals::GlobalRowsFromLocal> global_rows;
+
+ /**
+ * Data array for reorder row/column indices. Use a shared ptr to
+ * global_rows to avoid defining in the .h file
+ */
+ std_cxx1x::shared_ptr<internals::GlobalRowsFromLocal> global_columns;
+ };
+
+ /**
+ * Here comes the actual data structure for the scratch data. It is made
+ * mutable since it is modified in a const function. Since only one thread
+ * can access it at a time, no conflicting access can occur. For this to be
+ * valid, we need to make sure that no call within
+ * distribute_local_to_global is made that by itself can spawn
+ * tasks. Otherwise, we might end up in a situation where several threads
+ * fight for the data.
+ */
+ mutable Threads::ThreadLocalStorage<ScratchData> scratch_data;
+
+ /**
+ * Internal function to calculate the index of line @p line in the vector
* lines_cache using local_lines.
*/
size_type calculate_line_index (const size_type line) const;
/**
- * Return @p true if the weight of an
- * entry (the second element of the
- * pair) equals zero. This function is
- * used to delete entries with zero
- * weight.
+ * Return @p true if the weight of an entry (the second element of the pair)
+ * equals zero. This function is used to delete entries with zero weight.
*/
static bool check_zero_weight (const std::pair<size_type, double> &p);
/**
- * Dummy table that serves as default
- * argument for function
+ * Dummy table that serves as default argument for function
* <tt>add_entries_local_to_global()</tt>.
*/
static const Table<2,bool> default_empty_table;
/**
- * This function actually implements
- * the local_to_global function for
+ * This function actually implements the local_to_global function for
* standard (non-block) matrices.
*/
template <typename MatrixType, typename VectorType>
internal::bool2type<false>) const;
/**
- * This function actually implements
- * the local_to_global function for
- * block matrices.
+ * This function actually implements the local_to_global function for block
+ * matrices.
*/
template <typename MatrixType, typename VectorType>
void
internal::bool2type<true>) const;
/**
- * This function actually implements
- * the local_to_global function for
+ * This function actually implements the local_to_global function for
* standard (non-block) sparsity types.
*/
template <typename SparsityType>
internal::bool2type<false>) const;
/**
- * This function actually implements
- * the local_to_global function for
- * block sparsity types.
+ * This function actually implements the local_to_global function for block
+ * sparsity types.
*/
template <typename SparsityType>
void
internal::bool2type<true>) const;
/**
- * Internal helper function for
- * distribute_local_to_global function.
+ * Internal helper function for distribute_local_to_global function.
*
- * Creates a list of affected global rows
- * for distribution, including the local
- * rows where the entries come from. The
- * list is sorted according to the global
- * row indices.
+ * Creates a list of affected global rows for distribution, including the
+ * local rows where the entries come from. The list is sorted according to
+ * the global row indices.
*/
void
make_sorted_row_list (const std::vector<size_type> &local_dof_indices,
internals::GlobalRowsFromLocal &global_rows) const;
/**
- * Internal helper function for
- * add_entries_local_to_global function.
+ * Internal helper function for add_entries_local_to_global function.
*
- * Creates a list of affected rows for
- * distribution without any additional
- * information, otherwise similar to the
- * other make_sorted_row_list()
+ * Creates a list of affected rows for distribution without any additional
+ * information, otherwise similar to the other make_sorted_row_list()
* function.
*/
void
std::vector<size_type> &active_dofs) const;
/**
- * Internal helper function for
- * distribute_local_to_global function.
+ * Internal helper function for distribute_local_to_global function.
*/
double
resolve_vector_entry (const size_type i,
:
lines (),
local_lines (local_constraints),
- sorted (false)
+ sorted (false),
+ scratch_data (ScratchData())
{
// make sure the IndexSet is compressed. Otherwise this can lead to crashes
// that are hard to find (only happen in release mode).
lines (constraint_matrix.lines),
lines_cache (constraint_matrix.lines_cache),
local_lines (constraint_matrix.local_lines),
- sorted (constraint_matrix.sorted)
+ sorted (constraint_matrix.sorted),
+ scratch_data (ScratchData())
{}
{
Assert (sorted==false, ExcMatrixIsClosed());
- // the following can happen when we
- // compute with distributed meshes
- // and dof handlers and we
- // constrain a degree of freedom
- // whose number we don't have
- // locally. if we don't abort here
- // the program will try to allocate
- // several terabytes of memory to
- // resize the various arrays below
- // :-)
+ // the following can happen when we compute with distributed meshes and dof
+ // handlers and we constrain a degree of freedom whose number we don't have
+ // locally. if we don't abort here the program will try to allocate several
+ // terabytes of memory to resize the various arrays below :-)
Assert (line != numbers::invalid_size_type,
ExcInternalError());
const size_type line_index = calculate_line_index (line);
- // check whether line already exists; it
- // may, in which case we can just quit
+ // check whether line already exists; it may, in which case we can just quit
if (is_constrained(line))
return;
- // if necessary enlarge vector of
- // existing entries for cache
+ // if necessary enlarge vector of existing entries for cache
if (line_index >= lines_cache.size())
lines_cache.resize (std::max(2*static_cast<size_type>(lines_cache.size()),
line_index+1),
numbers::invalid_size_type);
- // push a new line to the end of the
- // list
+ // push a new line to the end of the list
lines.push_back (ConstraintLine());
lines.back().line = line;
lines.back().inhomogeneity = 0.;
Assert (line != column,
ExcMessage ("Can't constrain a degree of freedom to itself"));
- // if in debug mode, check whether an
- // entry for this column already
- // exists and if it's the same as
- // the one entered at present
+ // if in debug mode, check whether an entry for this column already exists
+ // and if it's the same as the one entered at present
//
- // in any case: exit the function if an
- // entry for this column already exists,
- // since we don't want to enter it twice
+ // in any case: exit the function if an entry for this column already
+ // exists, since we don't want to enter it twice
Assert (lines_cache[calculate_line_index(line)] != numbers::invalid_size_type,
ExcInternalError());
ConstraintLine *line_ptr = &lines[lines_cache[calculate_line_index(line)]];
bool
ConstraintMatrix::is_inhomogeneously_constrained (const size_type index) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(index);
if (line_index >= lines_cache.size() ||
const std::vector<std::pair<types::global_dof_index,double> > *
ConstraintMatrix::get_constraint_entries (const size_type line) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(line);
if (line_index >= lines_cache.size() ||
double
ConstraintMatrix::get_inhomogeneity (const size_type line) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(line);
if (line_index >= lines_cache.size() ||
const std::vector<size_type> &local_dof_indices,
MatrixType &global_matrix) const
{
- // create a dummy and hand on to the
- // function actually implementing this
+ // create a dummy and hand on to the function actually implementing this
// feature in the cm.templates.h file.
Vector<double> dummy(0);
distribute_local_to_global (local_matrix, dummy, local_dof_indices,
VectorType &global_vector,
bool use_inhomogeneities_for_rhs) const
{
- // enter the internal function with the
- // respective block information set, the
- // actual implementation follows in the
- // cm.templates.h file.
+ // enter the internal function with the respective block information set,
+ // the actual implementation follows in the cm.templates.h file.
distribute_local_to_global (local_matrix, local_vector, local_dof_indices,
global_matrix, global_vector, use_inhomogeneities_for_rhs,
internal::bool2type<IsBlockMatrix<MatrixType>::value>());
const bool keep_constrained_entries,
const Table<2,bool> &dof_mask) const
{
- // enter the internal function with the
- // respective block information set, the
- // actual implementation follows in the
- // cm.templates.h file.
+ // enter the internal function with the respective block information set,
+ // the actual implementation follows in the cm.templates.h file.
add_entries_local_to_global (local_dof_indices, sparsity_pattern,
keep_constrained_entries, dof_mask,
internal::bool2type<IsBlockMatrix<SparsityType>::value>());
-// Some helper definitions for the
-// local_to_global functions.
+// Some helper definitions for the local_to_global functions.
namespace internals
{
typedef types::global_dof_index size_type;
- // this struct contains all the information
- // we need to store about each of the
- // global entries (global_row): are they
- // obtained directly by some local entry
- // (local_row) or some constraints
- // (constraint_position). This is not
- // directly used in the user code, but
- // accessed via the
- // GlobalRowsFromLocal.
+ // this struct contains all the information we need to store about each of
+ // the global entries (global_row): are they obtained directly by some local
+ // entry (local_row) or some constraints (constraint_position). This is not
+ // directly used in the user code, but accessed via the GlobalRowsFromLocal.
//
- // The actions performed here correspond to
- // reshaping the constraint information
- // from global degrees of freedom to local
- // ones (i.e., cell-related DoFs), and also
- // transforming the constraint information
- // from compressed row storage (each local
- // dof that is constrained has a list of
- // constraint entries associated to it)
- // into compressed column storage based on
- // the cell-related DoFs (we have a list of
- // global degrees of freedom, and to each
- // we have a list of local rows where the
- // entries come from). To increase the
- // speed, we additionally store whether an
- // entry is generated directly from the
- // local degrees of freedom or whether it
- // comes from a constraint.
+ // The actions performed here correspond to reshaping the constraint
+ // information from global degrees of freedom to local ones (i.e.,
+ // cell-related DoFs), and also transforming the constraint information from
+ // compressed row storage (each local dof that is constrained has a list of
+ // constraint entries associated to it) into compressed column storage based
+ // on the cell-related DoFs (we have a list of global degrees of freedom,
+ // and to each we have a list of local rows where the entries come from). To
+ // increase the speed, we additionally store whether an entry is generated
+ // directly from the local degrees of freedom or whether it comes from a
+ // constraint.
struct Distributing
{
Distributing (const size_type global_row = numbers::invalid_size_type,
{
global_row = in.global_row;
local_row = in.local_row;
- // the constraints pointer should not
- // contain any data here.
+ // the constraints pointer should not contain any data here.
Assert (constraint_position == numbers::invalid_size_type,
ExcInternalError());
- // this is a cache for constraints that
- // are encountered on a local level.
+ // this is a cache for constraints that are encountered on a local level.
// The functionality is similar to
- // std::vector<std::vector<std::pair<uint,double>
- // > >, but tuned so that frequent memory
- // allocation for each entry is
- // avoided. This is not directly used in
- // the user code, but accessed via the
- // GlobalRowsFromLocal.
+ // std::vector<std::vector<std::pair<uint,double> > >, but tuned so that
+ // frequent memory allocation for each entry is avoided. The data is put
+ // into a std::vector<std::pair<uint,double> > and the row length is kept
+ // fixed at row_length. Both the number of rows and the row length can
+ // change is this structure is filled. In that case, the data is
+ // rearranged. This is not directly used in the user code, but accessed via
+ // the GlobalRowsFromLocal.
struct DataCache
{
DataCache ()
:
- element_size (0),
- data (0),
- n_used_elements(0)
+ row_length (8)
{}
- ~DataCache()
- {
- delete [] data;
- data = 0;
- }
-
void reinit ()
{
- Assert (element_size == 0, ExcInternalError());
- element_size = 6;
- data = new std::pair<size_type,double> [20*6];
- individual_size.resize(20);
- n_used_elements = 0;
+ individual_size.resize(0);
+ data.resize(0);
}
- size_type element_size;
-
- std::pair<size_type,double> *data;
-
- std::vector<size_type> individual_size;
-
- size_type n_used_elements;
-
size_type insert_new_index (const std::pair<size_type,double> &pair)
{
- if (element_size == 0)
- reinit();
- if (n_used_elements == individual_size.size())
- {
- std::pair<size_type,double> *new_data =
- new std::pair<size_type,double> [2*individual_size.size()*element_size];
- memcpy (new_data, data, individual_size.size()*element_size*
- sizeof(std::pair<size_type,double>));
- delete [] data;
- data = new_data;
- individual_size.resize (2*individual_size.size(), 0);
- }
- size_type index = n_used_elements;
- data[index*element_size] = pair;
+ Assert(row_length > 0, ExcInternalError());
+ const unsigned int index = individual_size.size();
+ individual_size.push_back(1);
+ data.resize(individual_size.size()*row_length);
+ data[index*row_length] = pair;
individual_size[index] = 1;
- ++n_used_elements;
return index;
}
void append_index (const size_type index,
const std::pair<size_type,double> &pair)
{
- AssertIndexRange (index, n_used_elements);
- const size_type my_size = individual_size[index];
- if (my_size == element_size)
+ AssertIndexRange (index, individual_size.size());
+ const size_type my_length = individual_size[index];
+ if (my_length == row_length)
{
- std::pair<size_type,double> *new_data =
- new std::pair<size_type,double> [2*individual_size.size()*element_size];
- for (size_type i=0; i<n_used_elements; ++i)
- memcpy (&new_data[i*element_size*2], &data[i*element_size],
- element_size*sizeof(std::pair<size_type,double>));
- delete [] data;
- data = new_data;
- element_size *= 2;
+ AssertDimension(data.size(), individual_size.size()*row_length);
+ // no space left in this row, need to double row_length and
+ // rearrange the data items
+ data.resize(2*data.size());
+ for (size_type i=individual_size.size(); i>0; )
+ {
+ --i;
+ std::memmove(&data[i*row_length*2], &data[i*row_length],
+ individual_size[i]*
+ sizeof(std::pair<size_type,double>));
+ }
+ row_length *= 2;
}
- data[index*element_size+my_size] = pair;
- individual_size[index]++;
+ data[index*row_length+my_length] = pair;
+ individual_size[index] = my_length + 1;
}
size_type
const std::pair<size_type,double> *
get_entry (const size_type index) const
{
- return &data[index*element_size];
+ return &data[index*row_length];
}
+
+ size_type row_length;
+
+ std::vector<std::pair<size_type,double> > data;
+
+ std::vector<size_type> individual_size;
};
- // collects all the global rows from a
- // local contribution (cell) and their
- // origin (direct/constraint). this is
- // basically a vector consisting of
- // "Distributing" structs using access via
- // the DataCache. Provides some
+ // collects all the global rows from a local contribution (cell) and their
+ // origin (direct/constraint). this is basically a vector consisting of
+ // "Distributing" structs using access via the DataCache. Provides some
// specialized sort and insert functions.
//
- // in case there are no constraints, this is
- // basically a list of pairs <uint,unit> with
- // the first index being the global index and
- // the second index the local index. The list
- // is sorted with respect to the global index.
+ // in case there are no constraints, this is basically a list of pairs
+ // <uint,unit> with the first index being the global index and the second
+ // index the local index. The list is sorted with respect to the global
+ // index.
//
- // in case there are constraints, a global dof
- // might get a contribution also because it
- // gets data from a constrained dof. This
- // means that a global dof might also have
- // indirect contributions from a local dof via
- // a constraint, besides the direct ones.
+ // in case there are constraints, a global dof might get a contribution also
+ // because it gets data from a constrained dof. This means that a global dof
+ // might also have indirect contributions from a local dof via a constraint,
+ // besides the direct ones.
//
- // The actions performed here correspond to
- // reshaping the constraint information
- // from global degrees of freedom to local
- // ones (i.e., cell-related DoFs), and also
- // transforming the constraint information
- // from compressed row storage (each local
- // dof that is constrained has a list of
- // constraint entries associated to it)
- // into compressed column storage based on
- // the cell-related DoFs (we have a list of
- // global degrees of freedom, and to each
- // we have a list of local rows where the
- // entries come from). To increase the
- // speed, we additionally store whether an
- // entry is generated directly from the
- // local degrees of freedom or whether it
- // comes from a constraint.
+ // The actions performed here correspond to reshaping the constraint
+ // information from global degrees of freedom to local ones (i.e.,
+ // cell-related DoFs), and also transforming the constraint information from
+ // compressed row storage (each local dof that is constrained has a list of
+ // constraint entries associated to it) into compressed column storage based
+ // on the cell-related DoFs (we have a list of global degrees of freedom,
+ // and to each we have a list of local rows where the entries come from). To
+ // increase the speed, we additionally store whether an entry is generated
+ // directly from the local degrees of freedom or whether it comes from a
+ // constraint.
class GlobalRowsFromLocal
{
public:
- GlobalRowsFromLocal (const size_type n_local_rows)
+ GlobalRowsFromLocal ()
:
- total_row_indices (n_local_rows),
- n_active_rows (n_local_rows),
+ n_active_rows (0),
n_inhomogeneous_rows (0)
{}
+ void reinit (const size_type n_local_rows)
+ {
+ total_row_indices.resize(n_local_rows);
+ for (unsigned int i=0; i<n_local_rows; ++i)
+ total_row_indices[i].constraint_position = numbers::invalid_size_type;
+ n_active_rows = n_local_rows;
+ n_inhomogeneous_rows = 0;
+ data_cache.reinit();
+ }
// implemented below
void insert_index (const size_type global_row,
const double constraint_value);
void sort ();
- // Print object for debugging
- // purpose
+ // Print object for debugging purpose
void print(std::ostream &os)
{
os << "Active rows " << n_active_rows << std::endl
}
- // return all kind of information on the
- // constraints
+ // return all kind of information on the constraints
- // returns the number of global indices in the
- // struct
+ // returns the number of global indices in the struct
size_type size () const
{
return n_active_rows;
}
- // returns the global index of the
+ // returns the number of constraints that are associated to the
// counter_index-th entry in the list
- size_type &global_row (const size_type counter_index)
- {
- return total_row_indices[counter_index].global_row;
- }
-
- // returns the number of constraints that are
- // associated to the counter_index-th entry in
- // the list
size_type size (const size_type counter_index) const
{
return (total_row_indices[counter_index].constraint_position ==
constraint_position));
}
- // returns the global row associated with the
- // counter_index-th entry in the list
- const size_type &global_row (const size_type counter_index) const
+ // returns the global row of the counter_index-th entry in the list
+ size_type global_row (const size_type counter_index) const
+ {
+ return total_row_indices[counter_index].global_row;
+ }
+
+ // returns the global row of the counter_index-th entry in the list
+ size_type &global_row (const size_type counter_index)
{
return total_row_indices[counter_index].global_row;
}
- // returns the local row in the cell matrix
- // associated with the counter_index-th entry
- // in the list. Returns invalid_size_type
- // for invalid size_types
- const size_type &local_row (const size_type counter_index) const
+ // returns the local row in the cell matrix associated with the
+ // counter_index-th entry in the list. Returns invalid_size_type for
+ // constrained rows
+ size_type local_row (const size_type counter_index) const
{
return total_row_indices[counter_index].local_row;
}
return total_row_indices[counter_index].local_row;
}
- // returns the local row in the cell matrix
- // associated with the counter_index-th entry
- // in the list in the index_in_constraint-th
+ // returns the local row in the cell matrix associated with the
+ // counter_index-th entry in the list in the index_in_constraint-th
// position of constraints
size_type local_row (const size_type counter_index,
const size_type index_in_constraint) const
[index_in_constraint]).first;
}
- // returns the value of the constraint in the
- // counter_index-th entry in the list in the
- // index_in_constraint-th position of
- // constraints
+ // returns the value of the constraint in the counter_index-th entry in
+ // the list in the index_in_constraint-th position of constraints
double constraint_value (const size_type counter_index,
const size_type index_in_constraint) const
{
[index_in_constraint]).second;
}
- // returns whether there is one row with
- // indirect contributions (i.e., there has
- // been at least one constraint with
- // non-trivial ConstraintLine)
+ // returns whether there is one row with indirect contributions (i.e.,
+ // there has been at least one constraint with non-trivial ConstraintLine)
bool have_indirect_rows () const
{
- return data_cache.element_size;
+ return data_cache.individual_size.empty() == false;
}
- // append an entry that is
- // constrained. This means that
- // there is one less nontrivial
- // row
+ // append an entry that is constrained. This means that there is one less
+ // nontrivial row
void insert_constraint (const size_type constrained_local_dof)
{
--n_active_rows;
total_row_indices[n_active_rows].local_row = constrained_local_dof;
+ total_row_indices[n_active_rows].global_row = numbers::invalid_size_type;
}
- // returns the number of constrained
- // dofs in the structure. Constrained
- // dofs do not contribute directly to
- // the matrix, but are needed in order
- // to set matrix diagonals and resolve
- // inhomogeneities
+ // returns the number of constrained dofs in the structure. Constrained
+ // dofs do not contribute directly to the matrix, but are needed in order
+ // to set matrix diagonals and resolve inhomogeneities
size_type n_constraints () const
{
return total_row_indices.size()-n_active_rows;
}
- // returns the number of constrained
- // dofs in the structure that have an
+ // returns the number of constrained dofs in the structure that have an
// inhomogeneity
size_type n_inhomogeneities () const
{
return n_inhomogeneous_rows;
}
- // tells the structure that the ith
- // constraint is
- // inhomogeneous. inhomogeneous
- // constraints contribute to right hand
- // sides, so to have fast access to
- // them, put them before homogeneous
+ // tells the structure that the ith constraint is
+ // inhomogeneous. inhomogeneous constraints contribute to right hand
+ // sides, so to have fast access to them, put them before homogeneous
// constraints
void set_ith_constraint_inhomogeneous (const size_type i)
{
n_inhomogeneous_rows++;
}
- // the local row where
- // constraint number i was
- // detected, to find that row
- // easily when the
- // GlobalRowsToLocal has been
- // set up
+ // the local row where constraint number i was detected, to find that row
+ // easily when the GlobalRowsToLocal has been set up
size_type constraint_origin (size_type i) const
{
return total_row_indices[n_active_rows+i].local_row;
}
- // a vector that contains all the
- // global ids and the corresponding
- // local ids as well as a pointer to
- // that data where we store how to
- // resolve constraints.
+ // a vector that contains all the global ids and the corresponding local
+ // ids as well as a pointer to that data where we store how to resolve
+ // constraints.
std::vector<Distributing> total_row_indices;
private:
- // holds the actual data from
- // the constraints
+ // holds the actual data from the constraints
DataCache data_cache;
- // how many rows there are,
- // constraints disregarded
+ // how many rows there are, constraints disregarded
size_type n_active_rows;
- // the number of rows with
- // inhomogeneous constraints
+ // the number of rows with inhomogeneous constraints
size_type n_inhomogeneous_rows;
};
- // a function that appends an additional
- // row to the list of values, or appends a
- // value to an already existing
- // row. Similar functionality as for
- // std::map<size_type,Distributing>, but
- // here done for a
- // std::vector<Distributing>, much faster
- // for short lists as we have them here
+ // a function that appends an additional row to the list of values, or
+ // appends a value to an already existing row. Similar functionality as for
+ // std::map<size_type,Distributing>, but here done for a
+ // std::vector<Distributing>, much faster for short lists as we have them
+ // here
inline
void
GlobalRowsFromLocal::insert_index (const size_type global_row,
Distributing row_value (global_row);
std::pair<size_type,double> constraint (local_row, constraint_value);
- // check whether the list was really
- // sorted before entering here
+ // check whether the list was really sorted before entering here
for (size_type i=1; i<n_active_rows; ++i)
Assert (total_row_indices[i-1] < total_row_indices[i], ExcInternalError());
data_cache.append_index (pos1->constraint_position, constraint);
}
- // this sort algorithm sorts
- // std::vector<Distributing>, but does not
- // take the constraints into account. this
- // means that in case that constraints are
- // already inserted, this function does not
- // work as expected. Use shellsort, which
- // is very fast in case the indices are
- // already sorted (which is the usual case
- // with DG elements), and not too slow in
- // other cases
+ // this sort algorithm sorts std::vector<Distributing>, but does not take
+ // the constraints into account. this means that in case that constraints
+ // are already inserted, this function does not work as expected. Use
+ // shellsort, which is very fast in case the indices are already sorted
+ // (which is the usual case with DG elements), and not too slow in other
+ // cases
inline
void
GlobalRowsFromLocal::sort ()
size_type i, j, j2, temp, templ, istep;
size_type step;
- // check whether the
- // constraints are really empty.
+ // check whether the constraints are really empty.
const size_type length = size();
- // make sure that we are in the
- // range of the vector
+ // make sure that we are in the range of the vector
AssertIndexRange (length, total_row_indices.size()+1);
for (size_type i=0; i<length; ++i)
Assert (total_row_indices[i].constraint_position ==
}
}
- // function for block matrices: Find out
- // where in the list of local dofs (sorted
- // according to global ids) the individual
- // blocks start. Transform the global
- // indices to block-local indices in order
- // to be able to use functions like
- // vector.block(1)(block_local_id), instead
- // of vector(global_id). This avoids
- // transforming indices one-by-one later
- // on.
+ // function for block matrices: Find out where in the list of local dofs
+ // (sorted according to global ids) the individual blocks start. Transform
+ // the global indices to block-local indices in order to be able to use
+ // functions like vector.block(1)(block_local_id), instead of
+ // vector(global_id). This avoids transforming indices one-by-one later on.
template <class BlockType>
inline
void
block_starts[i] = first_block - global_rows.total_row_indices.begin();
block_indices = first_block;
}
+ block_starts[num_blocks] = n_active_rows;
- // transform row indices to block-local
- // index space
+ // transform row indices to block-local index space
for (size_type i=block_starts[1]; i<n_active_rows; ++i)
global_rows.global_row(i) = block_object.get_row_indices().
global_to_local(global_rows.global_row(i)).second;
- // same as before, but for
- // std::vector<uint> instead of
- // GlobalRowsFromLocal. Used in functions
- // for sparsity patterns.
+ // same as before, but for std::vector<uint> instead of
+ // GlobalRowsFromLocal. Used in functions for sparsity patterns.
template <class BlockType>
inline
void
block_starts[i] = first_block - row_indices.begin();
col_indices = first_block;
}
+ block_starts[num_blocks] = row_indices.size();
- // transform row indices to local index
- // space
+ // transform row indices to local index space
for (size_type i=block_starts[1]; i<row_indices.size(); ++i)
row_indices[i] = block_object.get_row_indices().
global_to_local(row_indices[i]).second;
- // resolves constraints of one column at
- // the innermost loop. goes through the
- // origin of each global entry and finds
- // out which data we need to collect.
+ // resolves constraints of one column at the innermost loop. goes through
+ // the origin of each global entry and finds out which data we need to
+ // collect.
static inline
double resolve_matrix_entry (const GlobalRowsFromLocal &global_rows,
const GlobalRowsFromLocal &global_cols,
const size_type loc_col = global_cols.local_row(j);
double col_val;
- // case 1: row has direct contribution in
- // local matrix. decide whether col has a
- // direct contribution. if not,
- // set the value to zero.
+ // case 1: row has direct contribution in local matrix. decide whether col
+ // has a direct contribution. if not, set the value to zero.
if (loc_row != numbers::invalid_size_type)
{
col_val = ((loc_col != numbers::invalid_size_type) ?
local_matrix(loc_row, loc_col) : 0);
- // account for indirect contributions by
- // constraints in column
+ // account for indirect contributions by constraints in column
for (size_type p=0; p<global_cols.size(j); ++p)
col_val += (local_matrix(loc_row, global_cols.local_row(j,p)) *
global_cols.constraint_value(j,p));
}
- // case 2: row has no direct contribution in
- // local matrix
+ // case 2: row has no direct contribution in local matrix
else
col_val = 0;
- // account for indirect contributions by
- // constraints in row, going trough the
- // direct and indirect references in the
- // given column.
+ // account for indirect contributions by constraints in row, going trough
+ // the direct and indirect references in the given column.
for (size_type q=0; q<global_rows.size(i); ++q)
{
double add_this = (loc_col != numbers::invalid_size_type)
- // computes all entries that need to be
- // written into global_rows[i]. Lists the
- // resulting values in val_ptr, and the
- // corresponding column indices in col_ptr.
+ // computes all entries that need to be written into global_rows[i]. Lists
+ // the resulting values in val_ptr, and the corresponding column indices in
+ // col_ptr.
template <typename number>
inline
void
AssertIndexRange (column_end-1, global_cols.size());
const size_type loc_row = global_rows.local_row(i);
- // fast function if there are no indirect
- // references to any of the local rows at
- // all on this set of dofs (saves a lot
- // of checks). the only check we actually
- // need to perform is whether the matrix
- // element is zero.
+ // fast function if there are no indirect references to any of the local
+ // rows at all on this set of dofs (saves a lot of checks). the only check
+ // we actually need to perform is whether the matrix element is zero.
if (global_rows.have_indirect_rows() == false &&
global_cols.have_indirect_rows() == false)
{
}
}
- // more difficult part when there are
- // indirect references and when we need
+ // more difficult part when there are indirect references and when we need
// to do some more checks.
else
{
double col_val = resolve_matrix_entry (global_rows, global_cols, i, j,
loc_row, local_matrix);
- // if we got some nontrivial value,
- // append it to the array of values.
+ // if we got some nontrivial value, append it to the array of
+ // values.
if (col_val != 0.)
{
*val_ptr++ = static_cast<number> (col_val);
- // specialized function that can write into
- // the row of a SparseMatrix<number>.
+ // specialized function that can write into the row of a
+ // SparseMatrix<number>.
namespace dealiiSparseMatrix
{
template <typename SparseMatrixIterator>
}
- // similar as before, now with shortcut for
- // deal.II sparse matrices. this lets us
- // avoid using extra arrays, and does all the
- // operations just in place, i.e., in the
- // respective matrix row
+ // similar as before, now with shortcut for deal.II sparse matrices. this
+ // lets us avoid using extra arrays, and does all the operations just in
+ // place, i.e., in the respective matrix row
template <typename number>
inline
void
matrix_values = sparse_matrix->begin(row);
const bool optimize_diagonal = sparsity.n_rows() == sparsity.n_cols();
- // distinguish three cases about what can
- // happen for checking whether the diagonal is
- // the first element of the row. this avoids
- // if statements at the innermost loop
- // positions
+ // distinguish three cases about what can happen for checking whether the
+ // diagonal is the first element of the row. this avoids if statements at
+ // the innermost loop positions
if (!optimize_diagonal) // case 1: no diagonal optimization in matrix
{
}
}
}
- // case 3: can't say - need to check inside
- // the loop
+ // case 3: can't say - need to check inside the loop
else if (global_rows.have_indirect_rows() == false)
{
++matrix_values; // jump over diagonal element
- // Same function to resolve all entries that
- // will be added to the given global row
- // global_rows[i] as before, now for sparsity
- // pattern
+ // Same function to resolve all entries that will be added to the given
+ // global row global_rows[i] as before, now for sparsity pattern
inline
void
resolve_matrix_row (const GlobalRowsFromLocal &global_rows,
const size_type loc_row = global_rows.local_row(i);
- // fast function if there are no indirect
- // references to any of the local rows at
- // all on this set of dofs
+ // fast function if there are no indirect references to any of the local
+ // rows at all on this set of dofs
if (global_rows.have_indirect_rows() == false)
{
Assert(loc_row < dof_mask.n_rows(),
}
}
- // slower functions when there are
- // indirect references and when we need
- // to do some more checks.
+ // slower functions when there are indirect references and when we need to
+ // do some more checks.
else
{
for (size_type j=column_start; j<column_end; ++j)
}
continue;
- // if we got some nontrivial value,
- // append it to the array of values.
+ // if we got some nontrivial value, append it to the array of
+ // values.
add_this_index:
*col_ptr++ = global_rows.global_row(j);
}
- // to make sure that the global matrix
- // remains invertible, we need to do
- // something with the diagonal
- // elements. add the absolute value of
- // the local matrix, so the resulting
- // entry will always be positive and
- // furthermore be in the same order of
- // magnitude as the other elements of the
- // matrix
+ // to make sure that the global matrix remains invertible, we need to do
+ // something with the diagonal elements. add the absolute value of the local
+ // matrix, so the resulting entry will always be positive and furthermore be
+ // in the same order of magnitude as the other elements of the matrix
//
- // note that this also captures the
- // special case that a dof is both
- // constrained and fixed (this can
- // happen for hanging nodes in 3d that
- // also happen to be on the
- // boundary). in that case, following
- // the program flow in
- // distribute_local_to_global, it is
- // realized that when distributing the
- // row and column no elements of the
- // matrix are actually touched if all
- // the degrees of freedom to which this
- // dof is constrained are also
- // constrained (the usual case with
- // hanging nodes in 3d). however, in
- // the line below, we do actually do
- // something with this dof
+ // note that this also captures the special case that a dof is both
+ // constrained and fixed (this can happen for hanging nodes in 3d that also
+ // happen to be on the boundary). in that case, following the program flow
+ // in distribute_local_to_global, it is realized that when distributing the
+ // row and column no elements of the matrix are actually touched if all the
+ // degrees of freedom to which this dof is constrained are also constrained
+ // (the usual case with hanging nodes in 3d). however, in the line below, we
+ // do actually do something with this dof
template <typename MatrixType, typename VectorType>
inline void
set_matrix_diagonals (const internals::GlobalRowsFromLocal &global_rows,
std::fabs(local_matrix(local_row,local_row)) : average_diagonal);
global_matrix.add(global_row, global_row, new_diagonal);
- // if the use_inhomogeneities_for_rhs flag is
- // set to true, the inhomogeneities are used
- // to create the global vector. instead of
- // fill in a zero in the ith components with an
- // inhomogeneity, we set those to:
- // inhomogeneity(i)*global_matrix (i,i).
+ // if the use_inhomogeneities_for_rhs flag is set to true, the
+ // inhomogeneities are used to create the global vector. instead
+ // of fill in a zero in the ith components with an inhomogeneity,
+ // we set those to: inhomogeneity(i)*global_matrix (i,i).
if (use_inhomogeneities_for_rhs == true)
global_vector(global_row) += constraints.get_inhomogeneity(global_row) * new_diagonal;
}
- // similar function as the one above for
- // setting matrix diagonals, but now doing
- // that for sparsity patterns when setting
- // them up using
- // add_entries_local_to_global. In case we
- // keep constrained entries, add all the rows
- // and columns related to the constrained dof,
- // otherwise just add the diagonal
+ // similar function as the one above for setting matrix diagonals, but now
+ // doing that for sparsity patterns when setting them up using
+ // add_entries_local_to_global. In case we keep constrained entries, add all
+ // the rows and columns related to the constrained dof, otherwise just add
+ // the diagonal
template <typename SparsityType>
inline void
set_sparsity_diagonals (const internals::GlobalRowsFromLocal &global_rows,
- const std::vector<size_type> &local_dof_indices,
+ const std::vector<size_type> &local_dof_indices,
const Table<2,bool> &dof_mask,
const bool keep_constrained_entries,
SparsityType &sparsity_pattern)
{
- // if we got constraints, need to add
- // the diagonal element and, if the
- // user requested so, also the rest of
- // the entries in rows and columns
+ // if we got constraints, need to add the diagonal element and, if the
+ // user requested so, also the rest of the entries in rows and columns
// that have been left out above
if (global_rows.n_constraints() > 0)
{
}
}
else
- // don't keep constrained entries - just
- // add the diagonal.
+ // don't keep constrained entries - just add the diagonal.
sparsity_pattern.add(global_row,global_row);
}
}
// are related to it.
void
ConstraintMatrix::
-make_sorted_row_list (const std::vector<size_type> &local_dof_indices,
- internals::GlobalRowsFromLocal &global_rows) const
+make_sorted_row_list (const std::vector<size_type> &local_dof_indices,
+ internals::GlobalRowsFromLocal &global_rows) const
{
const size_type n_local_dofs = local_dof_indices.size();
AssertDimension (n_local_dofs, global_rows.size());
- // when distributing the local data to
- // the global matrix, we can quite
- // cheaply sort the indices (obviously,
- // this introduces the need for
- // allocating some memory on the way, but
- // we need to do this only for rows,
- // whereas the distribution process
- // itself goes over rows and
- // columns). This has the advantage that
- // when writing into the global matrix,
- // we can make use of the sortedness.
-
- // so the first step is to create a
- // sorted list of all row values that are
- // possible. these values are either the
- // rows from unconstrained dofs, or some
- // indices introduced by dofs constrained
- // to a combination of some other
- // dofs. regarding the data type, choose
- // an STL vector of a pair of unsigned
- // ints (for global columns) and internal
- // data (containing local columns +
- // possible jumps from
- // constraints). Choosing an STL map or
- // anything else M.K. knows of would be
- // much more expensive here!
-
- // cache whether we have to resolve any
- // indirect rows generated from resolving
- // constrained dofs.
+ // when distributing the local data to the global matrix, we can quite
+ // cheaply sort the indices (obviously, this introduces the need for
+ // allocating some memory on the way, but we need to do this only for rows,
+ // whereas the distribution process itself goes over rows and columns). This
+ // has the advantage that when writing into the global matrix, we can make
+ // use of the sortedness.
+
+ // so the first step is to create a sorted list of all row values that are
+ // possible. these values are either the rows from unconstrained dofs, or
+ // some indices introduced by dofs constrained to a combination of some
+ // other dofs. regarding the data type, choose an STL vector of a pair of
+ // unsigned ints (for global columns) and internal data (containing local
+ // columns + possible jumps from constraints). Choosing an STL map or
+ // anything else M.K. knows of would be much more expensive here!
+
+ // cache whether we have to resolve any indirect rows generated from
+ // resolving constrained dofs.
size_type added_rows = 0;
- // first add the indices in an unsorted
- // way and only keep track of the
- // constraints that appear. They are
- // resolved in a second step.
+ // first add the indices in an unsorted way and only keep track of the
+ // constraints that appear. They are resolved in a second step.
for (size_type i = 0; i<n_local_dofs; ++i)
{
if (is_constrained(local_dof_indices[i]) == false)
{
global_rows.global_row(added_rows) = local_dof_indices[i];
global_rows.local_row(added_rows++) = i;
- continue;
}
- global_rows.insert_constraint(i);
+ else
+ global_rows.insert_constraint(i);
}
global_rows.sort();
-// Same function as before, but now do
-// only extract the global indices
-// that come from the local ones
-// without storing their origin. Used
-// for sparsity pattern generation.
+// Same function as before, but now do only extract the global indices that
+// come from the local ones without storing their origin. Used for sparsity
+// pattern generation.
inline
void
ConstraintMatrix::
{
const size_type local_row = active_dofs.back();
- // remove constrained entry since we
- // are going to resolve it in place
+ // remove constrained entry since we are going to resolve it in place
active_dofs.pop_back();
const size_type global_row = local_dof_indices[local_row];
const ConstraintLine &position =
if (active_dofs[active_dofs.size()-i] < new_index)
active_dofs.insert(active_dofs.end()-i+1,new_index);
- // make binary search to find where to
- // put the new index in order to keep
- // the list sorted
+ // make binary search to find where to put the new index in order to
+ // keep the list sorted
else
{
std::vector<size_type>::iterator it =
-// Resolve the constraints from the vector and
-// apply inhomogeneities.
+// Resolve the constraints from the vector and apply inhomogeneities.
inline
double
ConstraintMatrix::
const size_type loc_row = global_rows.local_row(i);
const size_type n_inhomogeneous_rows = global_rows.n_inhomogeneities();
double val = 0;
- // has a direct contribution from some local
- // entry. If we have inhomogeneous
- // constraints, compute the contribution of
- // the inhomogeneity in the current row.
+ // has a direct contribution from some local entry. If we have inhomogeneous
+ // constraints, compute the contribution of the inhomogeneity in the current
+ // row.
if (loc_row != numbers::invalid_size_type)
{
val = local_vector(loc_row);
}
-// internal implementation for
-// distribute_local_to_global for
-// standard (non-block) matrices
+// internal implementation for distribute_local_to_global for standard
+// (non-block) matrices
template <typename MatrixType, typename VectorType>
void
ConstraintMatrix::distribute_local_to_global (
bool use_inhomogeneities_for_rhs,
internal::bool2type<false>) const
{
- // check whether we work on real vectors
- // or we just used a dummy when calling
- // the other function above.
+ // check whether we work on real vectors or we just used a dummy when
+ // calling the other function above.
const bool use_vectors = (local_vector.size() == 0 &&
global_vector.size() == 0) ? false : true;
typedef typename MatrixType::value_type number;
Assert (lines.empty() || sorted == true, ExcMatrixNotClosed());
const size_type n_local_dofs = local_dof_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ // TODO: might want to have a scoped variable for in_use here and in the
+ // methods below
+ my_scratch_data.in_use = true;
+
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // create arrays for the column data
- // (indices and values) that will then be
- // written into the matrix. Shortcut for
- // deal.II sparse matrix
- std::vector<size_type> cols;
- std::vector<number> vals;
+ // create arrays for the column data (indices and values) that will then be
+ // written into the matrix. Shortcut for deal.II sparse matrix. We can use
+ // the scratch data if we have a double matrix. Otherwise, we need to create
+ // an array in any case since we cannot know about the actual data type in
+ // the ConstraintMatrix class (unless we do cast). This involves a little
+ // bit of logic to determine the type of the matrix value.
+ std::vector<size_type> & cols = my_scratch_data.columns;
+ std::vector<double> & vals = my_scratch_data.values;
+ std::vector<number> values_non_double;
SparseMatrix<number> *sparse_matrix
= dynamic_cast<SparseMatrix<number> *>(&global_matrix);
if (use_dealii_matrix == false)
{
cols.resize (n_actual_dofs);
- vals.resize (n_actual_dofs);
+ if (types_are_equal<double,number>::value == false)
+ values_non_double.resize(n_actual_dofs);
+ else
+ vals.resize (n_actual_dofs);
}
else
Assert (sparse_matrix != 0, ExcInternalError());
- // now do the actual job. go through all
- // the global rows that we will touch and
- // call resolve_matrix_row for each of
- // those.
+ // now do the actual job. go through all the global rows that we will touch
+ // and call resolve_matrix_row for each of those.
for (size_type i=0; i<n_actual_dofs; ++i)
{
const size_type row = global_rows.global_row(i);
- // calculate all the data that will be
- // written into the matrix row.
+ // calculate all the data that will be written into the matrix row.
if (use_dealii_matrix == false)
{
size_type *col_ptr = &cols[0];
- number *val_ptr = &vals[0];
+ // cast is uncritical here and only used to avoid compiler
+ // warnings. We never access a non-double array
+ number *val_ptr = types_are_equal<double,number>::value ?
+ reinterpret_cast<number*>(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_rows, i, 0,
n_actual_dofs,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type)(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
- global_matrix.add(row, n_values, &cols[0], &vals[0], false, true);
+ global_matrix.add(row, n_values, &cols[0], val_ptr-n_values, false,
+ true);
}
else
internals::resolve_matrix_row (global_rows, i, 0, n_actual_dofs,
local_matrix, sparse_matrix);
- // now to the vectors. besides doing the
- // same job as we did above (i.e.,
- // distribute the content of the local
- // vector into the global one), need to
- // account for inhomogeneities here: thie
- // corresponds to eliminating the
- // respective column in the local matrix
- // with value on the right hand side.
+ // now to the vectors. besides doing the same job as we did above (i.e.,
+ // distribute the content of the local vector into the global one), need
+ // to account for inhomogeneities here: thie corresponds to eliminating
+ // the respective column in the local matrix with value on the right
+ // hand side.
if (use_vectors == true)
{
const double val = resolve_vector_entry (i, global_rows,
internals::set_matrix_diagonals (global_rows, local_dof_indices,
local_matrix, *this,
global_matrix, global_vector, use_inhomogeneities_for_rhs);
+ my_scratch_data.in_use = false;
}
const size_type n_local_row_dofs = row_indices.size();
const size_type n_local_col_dofs = col_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_row_dofs);
- internals::GlobalRowsFromLocal global_cols (n_local_col_dofs);
+
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ if (my_scratch_data.global_columns.get() == 0)
+ my_scratch_data.global_columns.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_row_dofs);
+ internals::GlobalRowsFromLocal &global_cols = *my_scratch_data.global_columns;
+ global_cols.reinit(n_local_col_dofs);
make_sorted_row_list (row_indices, global_rows);
make_sorted_row_list (col_indices, global_cols);
const size_type n_actual_row_dofs = global_rows.size();
const size_type n_actual_col_dofs = global_cols.size();
- // create arrays for the column data
- // (indices and values) that will then be
- // written into the matrix. Shortcut for
- // deal.II sparse matrix
- std::vector<size_type> cols (n_actual_col_dofs);
- std::vector<number> vals (n_actual_col_dofs);
+ // create arrays for the column data (indices and values) that will then be
+ // written into the matrix. Shortcut for deal.II sparse matrix
+ std::vector<size_type> & cols = my_scratch_data.columns;
+ std::vector<double> & vals = my_scratch_data.values;
+ std::vector<number> values_non_double;
+ cols.resize(n_actual_col_dofs);
+ if (types_are_equal<double,number>::value == true)
+ vals.resize(n_actual_col_dofs);
+ else
+ values_non_double.resize(n_actual_col_dofs);
// now do the actual job.
for (size_type i=0; i<n_actual_row_dofs; ++i)
{
const size_type row = global_rows.global_row(i);
- // calculate all the data that will be
- // written into the matrix row.
+ // calculate all the data that will be written into the matrix row.
size_type *col_ptr = &cols[0];
- number *val_ptr = &vals[0];
+ number *val_ptr = types_are_equal<double,number>::value ?
+ reinterpret_cast<number*>(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_cols, i, 0,
n_actual_col_dofs,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type)(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
- global_matrix.add(row, n_values, &cols[0], &vals[0], false, true);
+ global_matrix.add(row, n_values, &cols[0], val_ptr-n_values,
+ false, true);
}
+
+ my_scratch_data.in_use = false;
}
-// similar function as above, but now
-// specialized for block matrices. See
-// the other function for additional
-// comments.
+// similar function as above, but now specialized for block matrices. See the
+// other function for additional comments.
template <typename MatrixType, typename VectorType>
void
ConstraintMatrix::
}
Assert (sorted == true, ExcMatrixNotClosed());
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
const size_type n_local_dofs = local_dof_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
+
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- std::vector<size_type> global_indices;
+ std::vector<size_type> &global_indices = my_scratch_data.vector_indices;
if (use_vectors == true)
{
global_indices.resize(n_actual_dofs);
global_indices[i] = global_rows.global_row(i);
}
- // additional construct that also takes
- // care of block indices.
+ // additional construct that also takes care of block indices.
const size_type num_blocks = global_matrix.n_block_rows();
- std::vector<size_type> block_starts(num_blocks+1, n_actual_dofs);
+ std::vector<size_type> &block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
internals::make_block_starts (global_matrix, global_rows, block_starts);
- std::vector<size_type> cols;
- std::vector<number> vals;
+ std::vector<size_type> & cols = my_scratch_data.columns;
+ std::vector<double> & vals = my_scratch_data.values;
+ std::vector<number> values_non_double;
if (use_dealii_matrix == false)
{
cols.resize (n_actual_dofs);
- vals.resize (n_actual_dofs);
+ if (types_are_equal<double,number>::value == true)
+ vals.resize(n_actual_dofs);
+ else
+ values_non_double.resize(n_actual_dofs);
}
- // the basic difference to the non-block
- // variant from now onwards is that we go
- // through the blocks of the matrix
- // separately, which allows us to set the
- // block entries individually
+ // the basic difference to the non-block variant from now onwards is that we
+ // go through the blocks of the matrix separately, which allows us to set
+ // the block entries individually
for (size_type block=0; block<num_blocks; ++block)
{
const size_type next_block = block_starts[block+1];
if (use_dealii_matrix == false)
{
size_type *col_ptr = &cols[0];
- number *val_ptr = &vals[0];
+ number *val_ptr = types_are_equal<double,number>::value ?
+ reinterpret_cast<number*>(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_rows, i,
start_block, end_block,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type )(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
global_matrix.block(block, block_col).add(row, n_values,
- &cols[0], &vals[0],
+ &cols[0],
+ val_ptr-n_values,
false, true);
}
else
internals::set_matrix_diagonals (global_rows, local_dof_indices,
local_matrix, *this,
global_matrix, global_vector, use_inhomogeneities_for_rhs);
+
+ my_scratch_data.in_use = false;
}
AssertDimension (dof_mask.n_cols(), n_local_dofs);
}
- // if the dof mask is not active, all we
- // have to do is to add some indices in a
- // matrix format. To do this, we first
- // create an array of all the indices
- // that are to be added. these indices
- // are the local dof indices plus some
- // indices that come from constraints.
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
+ // if the dof mask is not active, all we have to do is to add some indices
+ // in a matrix format. To do this, we first create an array of all the
+ // indices that are to be added. these indices are the local dof indices
+ // plus some indices that come from constraints.
if (dof_mask_is_active == false)
{
- std::vector<size_type> actual_dof_indices (n_local_dofs);
+ std::vector<size_type> & actual_dof_indices = my_scratch_data.columns;
+ actual_dof_indices.resize(n_local_dofs);
make_sorted_row_list (local_dof_indices, actual_dof_indices);
const size_type n_actual_dofs = actual_dof_indices.size();
- // now add the indices we collected above
- // to the sparsity pattern. Very easy
- // here - just add the same array to all
- // the rows...
+ // now add the indices we collected above to the sparsity pattern. Very
+ // easy here - just add the same array to all the rows...
for (size_type i=0; i<n_actual_dofs; ++i)
sparsity_pattern.add_entries(actual_dof_indices[i],
actual_dof_indices.begin(),
actual_dof_indices.end(),
true);
- // need to add the whole row and column
- // structure in case we keep constrained
- // entries. Unfortunately, we can't use
- // the nice matrix structure we use
- // elsewhere, so manually add those
- // indices one by one.
+ // need to add the whole row and column structure in case we keep
+ // constrained entries. Unfortunately, we can't use the nice matrix
+ // structure we use elsewhere, so manually add those indices one by one.
for (size_type i=0; i<n_local_dofs; i++)
if (is_constrained(local_dof_indices[i]))
{
sparsity_pattern.add (local_dof_indices[i], local_dof_indices[i]);
}
+ my_scratch_data.in_use = false;
return;
}
- // complicated case: we need to filter
- // out some indices. then the function
- // gets similar to the function for
- // distributing matrix entries, see there
+ // complicated case: we need to filter out some indices. then the function
+ // gets similar to the function for distributing matrix entries, see there
// for additional comments.
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // create arrays for the column indices
- // that will then be written into the
+ // create arrays for the column indices that will then be written into the
// sparsity pattern.
- std::vector<size_type> cols (n_actual_dofs);
+ std::vector<size_type> & cols = my_scratch_data.columns;
+ cols.resize(n_actual_dofs);
for (size_type i=0; i<n_actual_dofs; ++i)
{
internals::resolve_matrix_row (global_rows, i, 0, n_actual_dofs,
dof_mask, col_ptr);
- // finally, write all the information
- // that accumulated under the given
- // process into the global matrix row and
- // into the vector
+ // finally, write all the information that accumulated under the given
+ // process into the global matrix row and into the vector
if (col_ptr != cols.begin())
sparsity_pattern.add_entries(row, cols.begin(), col_ptr,
true);
internals::set_sparsity_diagonals (global_rows, local_dof_indices,
dof_mask, keep_constrained_entries,
sparsity_pattern);
+ my_scratch_data.in_use = false;
}
ConstraintMatrix::
add_entries_local_to_global (const std::vector<size_type> &row_indices,
const std::vector<size_type> &col_indices,
- SparsityType &sparsity_pattern,
- const bool keep_constrained_entries,
- const Table<2,bool> &dof_mask) const
+ SparsityType &sparsity_pattern,
+ const bool keep_constrained_entries,
+ const Table<2,bool> &dof_mask) const
{
const size_type n_local_rows = row_indices.size();
const size_type n_local_cols = col_indices.size();
if (dof_mask.n_rows() == n_local_rows && dof_mask.n_cols() == n_local_cols)
dof_mask_is_active = true;
- // if the dof mask is not active, all we
- // have to do is to add some indices in a
- // matrix format. To do this, we first
- // create an array of all the indices
- // that are to be added. these indices
- // are the local dof indices plus some
- // indices that come from constraints.
+ // if the dof mask is not active, all we have to do is to add some indices
+ // in a matrix format. To do this, we first create an array of all the
+ // indices that are to be added. these indices are the local dof indices
+ // plus some indices that come from constraints.
if (dof_mask_is_active == false)
{
std::vector<size_type> actual_row_indices (n_local_rows);
make_sorted_row_list (col_indices, actual_col_indices);
const size_type n_actual_rows = actual_row_indices.size();
- // now add the indices we collected above
- // to the sparsity pattern. Very easy
- // here - just add the same array to all
- // the rows...
+ // now add the indices we collected above to the sparsity pattern. Very
+ // easy here - just add the same array to all the rows...
for (size_type i=0; i<n_actual_rows; ++i)
sparsity_pattern.add_entries(actual_row_indices[i],
actual_col_indices.begin(),
return;
}
- // if constrained entries should be
- // kept, need to add rows and columns
- // of those to the sparsity pattern
+ // if constrained entries should be kept, need to add rows and columns of
+ // those to the sparsity pattern
if (keep_constrained_entries == true)
{
for (size_type i=0; i<row_indices.size(); i++)
const Table<2,bool> &dof_mask,
internal::bool2type<true> ) const
{
- // just as the other
- // add_entries_local_to_global function,
- // but now specialized for block
- // matrices.
+ // just as the other add_entries_local_to_global function, but now
+ // specialized for block matrices.
Assert (sparsity_pattern.n_rows() == sparsity_pattern.n_cols(), ExcNotQuadratic());
Assert (sparsity_pattern.n_block_rows() == sparsity_pattern.n_block_cols(),
ExcNotQuadratic());
const size_type n_local_dofs = local_dof_indices.size();
const size_type num_blocks = sparsity_pattern.n_block_rows();
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
bool dof_mask_is_active = false;
if (dof_mask.n_rows() == n_local_dofs)
{
if (dof_mask_is_active == false)
{
- std::vector<size_type> actual_dof_indices (n_local_dofs);
+ std::vector<size_type> & actual_dof_indices = my_scratch_data.columns;
+ actual_dof_indices.resize(n_local_dofs);
make_sorted_row_list (local_dof_indices, actual_dof_indices);
const size_type n_actual_dofs = actual_dof_indices.size();
- // additional construct that also takes
- // care of block indices.
- std::vector<size_type> block_starts(num_blocks+1, n_actual_dofs);
+ // additional construct that also takes care of block indices.
+ std::vector<size_type> &block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
internals::make_block_starts (sparsity_pattern, actual_dof_indices,
block_starts);
sparsity_pattern.add (local_dof_indices[i], local_dof_indices[i]);
}
+ my_scratch_data.in_use = false;
return;
}
- // difficult case with dof_mask, similar
- // to the distribute_local_to_global
+ // difficult case with dof_mask, similar to the distribute_local_to_global
// function for block matrices
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // additional construct that also takes
- // care of block indices.
- std::vector<size_type> block_starts(num_blocks+1, n_actual_dofs);
- internals::make_block_starts(sparsity_pattern, global_rows,
- block_starts);
+ // additional construct that also takes care of block indices.
+ std::vector<size_type> & block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
+ internals::make_block_starts(sparsity_pattern, global_rows, block_starts);
- std::vector<size_type> cols (n_actual_dofs);
+ std::vector<size_type> &cols = my_scratch_data.columns;
+ cols.resize(n_actual_dofs);
- // the basic difference to the
- // non-block variant from now onwards
- // is that we go through the blocks
- // of the matrix separately.
+ // the basic difference to the non-block variant from now onwards is that we
+ // go through the blocks of the matrix separately.
for (size_type block=0; block<num_blocks; ++block)
{
const size_type next_block = block_starts[block+1];
internals::set_sparsity_diagonals (global_rows, local_dof_indices,
dof_mask, keep_constrained_entries,
sparsity_pattern);
+ my_scratch_data.in_use = false;
}
DEAL_II_NAMESPACE_CLOSE
#endif
-
{
Assert (c.partitioner.get() != 0, ExcNotInitialized());
- // check whether the two vectors use the same
- // parallel partitioner. if not, check if all
- // local ranges are the same (that way, we can
- // exchange data between different parallel
- // layouts)
+ // check whether the two vectors use the same parallel partitioner. if
+ // not, check if all local ranges are the same (that way, we can
+ // exchange data between different parallel layouts)
if (partitioner.get() == 0)
reinit (c, true);
else if (partitioner.get() != c.partitioner.get())
* product (#vmult()) and scalar multiplication (#Tvmult()) functions
* of the Vector class.
*
- * @author Guidl Kanschat, 2006
+ * @author Guido Kanschat, 2006
*/
template <typename number>
class PointerMatrixVector : public PointerMatrixBase<Vector<number> >
"element."));
- // if for whatever reason we were
- // passed an empty map, return
+ // if for whatever reason we were passed an empty map, return
// immediately
if (function_map.size() == 0)
return;
std::vector<Point<spacedim> > dof_locations;
dof_locations.reserve (DoFTools::max_dofs_per_face(dof));
- // array to store the values of
- // the boundary function at the
- // boundary points. have two arrays
- // for scalar and vector functions
- // to use the more efficient one
- // respectively
+ // array to store the values of the boundary function at the boundary
+ // points. have two arrays for scalar and vector functions to use the
+ // more efficient one respectively
std::vector<double> dof_values_scalar;
std::vector<dealii::Vector<double> > dof_values_system;
dof_values_scalar.reserve (DoFTools::max_dofs_per_face (dof));
dof_values_system.reserve (DoFTools::max_dofs_per_face (dof));
- // before we start with the loop
- // over all cells create an
- // hp::FEValues object that holds
- // the interpolation points of all
- // finite elements that may ever be
- // in use
+ // before we start with the loop over all cells create an hp::FEValues
+ // object that holds the interpolation points of all finite elements
+ // that may ever be in use
dealii::hp::FECollection<dim,spacedim> finite_elements (dof.get_fe());
dealii::hp::QCollection<dim-1> q_collection;
for (unsigned int f=0; f<finite_elements.size(); ++f)
{
const FiniteElement<dim,spacedim> &fe = finite_elements[f];
- // generate a quadrature rule
- // on the face from the unit
- // support points. this will be
- // used to obtain the
- // quadrature points on the
+ // generate a quadrature rule on the face from the unit support
+ // points. this will be used to obtain the quadrature points on the
// real cell's face
//
- // to do this, we check whether
- // the FE has support points on
- // the face at all:
+ // to do this, we check whether the FE has support points on the
+ // face at all:
if (fe.has_face_support_points())
q_collection.push_back (Quadrature<dim-1>(fe.get_unit_face_support_points()));
else
{
- // if not, then we should
- // try a more clever
- // way. the idea is that a
- // finite element may not
- // offer support points for
- // all its shape functions,
- // but maybe only some. if
- // it offers support points
- // for the components we
- // are interested in in
- // this function, then
- // that's fine. if not, the
- // function we call in the
- // finite element will
- // raise an exception. the
- // support points for the
- // other shape functions
- // are left uninitialized
- // (well, initialized by
- // the default
- // constructor), since we
+ // if not, then we should try a more clever way. the idea is
+ // that a finite element may not offer support points for all
+ // its shape functions, but maybe only some. if it offers
+ // support points for the components we are interested in in
+ // this function, then that's fine. if not, the function we call
+ // in the finite element will raise an exception. the support
+ // points for the other shape functions are left uninitialized
+ // (well, initialized by the default constructor), since we
// don't need them anyway.
//
- // As a detour, we must
- // make sure we only query
- // face_system_to_component_index
- // if the index corresponds
- // to a primitive shape
- // function. since we know
- // that all the components
- // we are interested in are
- // primitive (by the above
- // check), we can safely
- // put such a check in
- // front
+ // As a detour, we must make sure we only query
+ // face_system_to_component_index if the index corresponds to a
+ // primitive shape function. since we know that all the
+ // components we are interested in are primitive (by the above
+ // check), we can safely put such a check in front
std::vector<Point<dim-1> > unit_support_points (fe.dofs_per_face);
for (unsigned int i=0; i<fe.dofs_per_face; ++i)
q_collection.push_back (Quadrature<dim-1>(unit_support_points));
}
}
- // now that we have a q_collection
- // object with all the right
- // quadrature points, create an
- // hp::FEFaceValues object that we
- // can use to evaluate the boundary
- // values at
+ // now that we have a q_collection object with all the right quadrature
+ // points, create an hp::FEFaceValues object that we can use to evaluate
+ // the boundary values at
dealii::hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
dealii::hp::FEFaceValues<dim,spacedim> x_fe_values (mapping_collection, finite_elements, q_collection,
update_quadrature_points);
{
const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- // we can presently deal only with
- // primitive elements for boundary
- // values. this does not preclude
- // us using non-primitive elements
- // in components that we aren't
- // interested in, however. make
- // sure that all shape functions
- // that are non-zero for the
- // components we are interested in,
+ // we can presently deal only with primitive elements for
+ // boundary values. this does not preclude us using
+ // non-primitive elements in components that we aren't
+ // interested in, however. make sure that all shape functions
+ // that are non-zero for the components we are interested in,
// are in fact primitive
for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
{
const typename DH::face_iterator face = cell->face(face_no);
const types::boundary_id boundary_component = face->boundary_indicator();
- // see if this face is
- // part of the
- // boundaries for which
- // we are supposed to
- // do something, and
- // also see if the
- // finite element in
- // use here has DoFs on
- // the face at all
+ // see if this face is part of the boundaries for which we are
+ // supposed to do something, and also see if the finite element
+ // in use here has DoFs on the face at all
if ((function_map.find(boundary_component) != function_map.end())
&&
(cell->get_fe().dofs_per_face > 0))
const dealii::FEFaceValues<dim,spacedim> &fe_values =
x_fe_values.get_present_fe_values();
- // get indices, physical location and
- // boundary values of dofs on this
- // face
+ // get indices, physical location and boundary values of
+ // dofs on this face
face_dofs.resize (fe.dofs_per_face);
face->get_dof_indices (face_dofs, cell->active_fe_index());
const std::vector<Point<spacedim> > &dof_locations
if (fe_is_system)
{
- // resize
- // array. avoid
- // construction of a
- // memory allocating
- // temporary if
- // possible
+ // resize array. avoid construction of a memory
+ // allocating temporary if possible
if (dof_values_system.size() < fe.dofs_per_face)
dof_values_system.resize (fe.dofs_per_face,
dealii::Vector<double>(fe.n_components()));
function_map.find(boundary_component)->second
->vector_value_list (dof_locations, dof_values_system);
- // enter those dofs
- // into the list that
- // match the
- // component
- // signature. avoid
- // the usual
- // complication that
- // we can't just use
- // *_system_to_component_index
- // for non-primitive
- // FEs
+ // enter those dofs into the list that match the
+ // component signature. avoid the usual complication
+ // that we can't just use *_system_to_component_index
+ // for non-primitive FEs
for (unsigned int i=0; i<face_dofs.size(); ++i)
{
unsigned int component;
component = fe.face_system_to_component_index(i).first;
else
{
- // non-primitive
- // case. make
- // sure that
- // this
- // particular
- // shape
- // function
- // _is_
- // primitive,
- // and get at
- // it's
- // component. use
- // usual
- // trick to
- // transfer
- // face dof
- // index to
- // cell dof
- // index
+ // non-primitive case. make sure that this
+ // particular shape function _is_ primitive, and
+ // get at it's component. use usual trick to
+ // transfer face dof index to cell dof index
const unsigned int cell_i
= (dim == 1 ?
i
numbers::invalid_unsigned_int)));
Assert (cell_i < fe.dofs_per_cell, ExcInternalError());
- // make sure
- // that if
- // this is
- // not a
- // primitive
- // shape function,
- // then all
- // the
- // corresponding
- // components
- // in the
- // mask are
- // not set
+ // make sure that if this is not a primitive
+ // shape function, then all the corresponding
+ // components in the mask are not set
if (!fe.is_primitive(cell_i))
for (unsigned int c=0; c<n_components; ++c)
if (fe.get_nonzero_components(cell_i)[c])
Assert (component_mask[c] == false,
FETools::ExcFENotPrimitive());
- // let's pick
- // the first
- // of
- // possibly
- // more than
- // one
- // non-zero
- // components. if
- // shape
- // function
- // is
- // non-primitive,
- // then we
- // will
- // ignore the
- // result in
- // the
- // following
- // anyway,
- // otherwise
- // there's
- // only one
- // non-zero
- // component
- // which we
- // will use
+ // let's pick the first of possibly more than
+ // one non-zero components. if shape function is
+ // non-primitive, then we will ignore the result
+ // in the following anyway, otherwise there's
+ // only one non-zero component which we will use
component = fe.get_nonzero_components(cell_i).first_selected_component();
}
}
}
else
- // fe has only one component,
- // so save some computations
+ // fe has only one component, so save some computations
{
- // get only the one component that
- // this function has
+ // get only the one component that this function has
dof_values_scalar.resize (fe.dofs_per_face);
function_map.find(boundary_component)->second
->value_list (dof_locations, dof_values_scalar, 0);
##
## ---------------------------------------------------------------------
+MESSAGE(STATUS "Setup library")
+
#
# Compile the deal.II library
#
DESTINATION ${DEAL_II_PROJECT_CONFIG_RELDIR}
COMPONENT library
)
+
+MESSAGE(STATUS "Setup library - Done")
return tria;
}
+ template<int dim, int spacedim>
+ const Triangulation<dim, spacedim> &
+ get_tria(const parallel::distributed::Triangulation<dim, spacedim> &tria)
+ {
+ return tria;
+ }
+
template<int dim, template<int, int> class Container, int spacedim>
const Triangulation<dim,spacedim> &
get_tria(const Container<dim,spacedim> &container)
return tria;
}
+ template<int dim, int spacedim>
+ Triangulation<dim, spacedim> &
+ get_tria(parallel::distributed::Triangulation<dim, spacedim> &tria)
+ {
+ return tria;
+ }
+
template<int dim, template<int, int> class Container, int spacedim>
const Triangulation<dim,spacedim> &
get_tria(Container<dim,spacedim> &container)
find_active_cell_around_point (const Container<dim,spacedim> &container,
const Point<spacedim> &p)
{
- return find_active_cell_around_point(StaticMappingQ1<dim,spacedim>::mapping,
- container, p).first;
+ return
+ find_active_cell_around_point<dim,Container,spacedim>
+ (StaticMappingQ1<dim,spacedim>::mapping,
+ container, p).first;
}
have_same_coarse_mesh (const Container &mesh_1,
const Container &mesh_2)
{
- return have_same_coarse_mesh (mesh_1.get_tria(),
- mesh_2.get_tria());
+ return have_same_coarse_mesh (get_tria(mesh_1),
+ get_tria(mesh_2));
}
- template<typename DH>
- std::vector<PeriodicFacePair<typename DH::cell_iterator> >
+ template<typename CONTAINER>
+ std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> >
collect_periodic_faces
- (const DH &dof_handler,
+ (const CONTAINER &container,
const types::boundary_id b_id1,
const types::boundary_id b_id2,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset)
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset)
{
- static const int dim = DH::dimension;
- static const int space_dim = DH::space_dimension;
+ static const int dim = CONTAINER::dimension;
+ static const int space_dim = CONTAINER::space_dimension;
Assert (0<=direction && direction<space_dim,
ExcIndexRange (direction, 0, space_dim));
// Loop over all cells on the highest level and collect all boundary
// faces belonging to b_id1 and b_id2:
- std::set<std::pair<typename DH::cell_iterator, unsigned int> > pairs1;
- std::set<std::pair<typename DH::cell_iterator, unsigned int> > pairs2;
+ std::set<std::pair<typename CONTAINER::cell_iterator, unsigned int> > pairs1;
+ std::set<std::pair<typename CONTAINER::cell_iterator, unsigned int> > pairs2;
- for (typename DH::cell_iterator cell = dof_handler.begin(0);
- cell != dof_handler.end(0); ++cell)
+ for (typename CONTAINER::cell_iterator cell = container.begin(0);
+ cell != container.end(0); ++cell)
{
for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
{
- const typename DH::face_iterator face = cell->face(i);
+ const typename CONTAINER::face_iterator face = cell->face(i);
if (face->at_boundary() && face->boundary_indicator() == b_id1)
{
- const std::pair<typename DH::cell_iterator, unsigned int> pair1
+ const std::pair<typename CONTAINER::cell_iterator, unsigned int> pair1
= std::make_pair(cell, i);
pairs1.insert(pair1);
}
if (face->at_boundary() && face->boundary_indicator() == b_id2)
{
- const std::pair<typename DH::cell_iterator, unsigned int> pair2
+ const std::pair<typename CONTAINER::cell_iterator, unsigned int> pair2
= std::make_pair(cell, i);
pairs2.insert(pair2);
}
- template<typename DH>
- std::vector<PeriodicFacePair<typename DH::cell_iterator> >
- collect_periodic_faces (const DH &dof_handler,
+ template<typename CONTAINER>
+ std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> >
+ collect_periodic_faces (const CONTAINER &container,
const types::boundary_id b_id,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset)
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset)
{
- static const int dim = DH::dimension;
- static const int space_dim = DH::space_dimension;
+ static const int dim = CONTAINER::dimension;
+ static const int space_dim = CONTAINER::space_dimension;
Assert (0<=direction && direction<space_dim,
ExcIndexRange (direction, 0, space_dim));
// Loop over all cells on the highest level and collect all boundary
// faces 2*direction and 2*direction*1:
- std::set<std::pair<typename DH::cell_iterator, unsigned int> > pairs1;
- std::set<std::pair<typename DH::cell_iterator, unsigned int> > pairs2;
+ std::set<std::pair<typename CONTAINER::cell_iterator, unsigned int> > pairs1;
+ std::set<std::pair<typename CONTAINER::cell_iterator, unsigned int> > pairs2;
- for (typename DH::cell_iterator cell = dof_handler.begin(0);
- cell != dof_handler.end(0); ++cell)
+ for (typename CONTAINER::cell_iterator cell = container.begin(0);
+ cell != container.end(0); ++cell)
{
- const typename DH::face_iterator face_1 = cell->face(2*direction);
- const typename DH::face_iterator face_2 = cell->face(2*direction+1);
+ const typename CONTAINER::face_iterator face_1 = cell->face(2*direction);
+ const typename CONTAINER::face_iterator face_2 = cell->face(2*direction+1);
if (face_1->at_boundary() && face_1->boundary_indicator() == b_id)
{
- const std::pair<typename DH::cell_iterator, unsigned int> pair1
+ const std::pair<typename CONTAINER::cell_iterator, unsigned int> pair1
= std::make_pair(cell, 2*direction);
pairs1.insert(pair1);
}
if (face_2->at_boundary() && face_2->boundary_indicator() == b_id)
{
- const std::pair<typename DH::cell_iterator, unsigned int> pair2
+ const std::pair<typename CONTAINER::cell_iterator, unsigned int> pair2
= std::make_pair(cell, 2*direction+1);
pairs2.insert(pair2);
}
// and call match_periodic_face_pairs that does the actual matching:
- typedef std::vector<PeriodicFacePair<typename DH::cell_iterator> >
+ typedef std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> >
FaceVector;
FaceVector matching = match_periodic_face_pairs(pairs1, pairs2,
}
+// now also instantiate these functions for parallel::distributed::Triangulation
+for (deal_II_dimension : DIMENSIONS ; deal_II_space_dimension : SPACE_DIMENSIONS)
+{
+
+#if deal_II_dimension <= deal_II_space_dimension
+ namespace GridTools \{
+
+ template
+ unsigned int
+ find_closest_vertex (const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &,
+ const Point<deal_II_space_dimension> &);
+
+ template
+ std::vector<parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension>::active_cell_iterator>
+ find_cells_adjacent_to_vertex(const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &,
+ const unsigned int);
+ template
+ parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension>::active_cell_iterator
+ find_active_cell_around_point (const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &,
+ const Point<deal_II_space_dimension> &p);
+
+ template
+ std::pair<parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension>::active_cell_iterator, Point<deal_II_dimension> >
+ find_active_cell_around_point (const Mapping<deal_II_dimension, deal_II_space_dimension> &,
+ const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &,
+ const Point<deal_II_space_dimension> &);
+
+ template
+ std::list<std::pair<parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension>::cell_iterator, parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension>::cell_iterator> >
+ get_finest_common_cells (const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &mesh_1,
+ const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &mesh_2);
+
+
+ template
+ bool
+ have_same_coarse_mesh (const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &mesh_1,
+ const parallel::distributed::Triangulation<deal_II_dimension,deal_II_space_dimension> &mesh_2);
+
+ \}
+
+ #endif
+}
+
+
+
for (deal_II_space_dimension : SPACE_DIMENSIONS)
{