download the development version of the library.
*/
+#include <algorithm>
+#include <assert.h>
+#include <cctype>
+#include <iostream>
+#include <limits>
+#include <list>
+#include <map>
+#include <set>
+#include <sstream>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "fpconfig.hh"
#ifdef FP_SUPPORT_OPTIMIZER
#include "fparser.hh"
int
lI2;
#else
-#include <stdint.h>
typedef
uint_least32_t
lI2;
nG
Set(Ref*p2){Have(p2);iC2;p=p2;}
#endif
-#include <utility>
e72
Compare2ndRev{nN1
T>inline
xE1;
#define FPHASH_CONST(x) x##ULL
#else
-#include <stdint.h>
typedef
uint_fast64_t
xE1;
#ifndef FPOptimizer_CodeTreeHH
#define FPOptimizer_CodeTreeHH
#ifdef FP_SUPPORT_OPTIMIZER
-#include <vector>
-#include <utility>
l33
lA1{e72
Grammar;}
#endif
#ifndef FPOptimizer_GrammarHH
#define FPOptimizer_GrammarHH
-#include <iostream>
t5{tK1
class
c02;}
xF::value;}
}
#ifdef FP_SUPPORT_OPTIMIZER
-#include <vector>
-#include <utility>
-#include <iostream>
nG1{using
l33
lA1;using
info,e32
tO3,std::ostream&o=cV2);}
#endif
-#include <string>
e42
lA1::nZ2
yT1=false);e42
iU1
yT1=false);
-#include <string>
-#include <sstream>
-#include <assert.h>
-#include <iostream>
using
l33
lA1;using
#endif
}
#ifdef FP_SUPPORT_OPTIMIZER
-#include <vector>
-#include <utility>
#ifndef FP_GENERATING_POWI_TABLE
enum{MAX_POWI_BYTECODE_LENGTH=20}
;
nI
iH2,false);}
}
-#include <vector>
-#include <map>
-#include <algorithm>
l33{using
l33
FUNCTIONPARSERTYPES;using
cM1)n4
eE3
t23}
-#include <limits>
l33{using
l33
FUNCTIONPARSERTYPES;using
xY3
return
t23}
-#include <list>
-#include <algorithm>
#ifdef FP_SUPPORT_OPTIMIZER
using
l33
}
#endif
#ifdef FP_SUPPORT_OPTIMIZER
-#include <sstream>
-#include <string>
-#include <map>
-#include <set>
-#include <iostream>
using
l33
FUNCTIONPARSERTYPES;
lA1;using
l33
FUNCTIONPARSERTYPES;
-#include <cctype>
l33
lA1{x83
ParamSpec_GetDepCode
<<depcode;}
}
}
-#include <algorithm>
using
l33
lA1;using
ENDIF()
+#
+# in intel (at least 13.1 and 14), vectorization causes
+# wrong code. See https://code.google.com/p/dealii/issues/detail?id=156
+# or tests/hp/solution_transfer.cc
+# A work-around is to disable all vectorization.
+#
+# - Timo Heister, 2013
+#
+IF(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+ ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS_RELEASE "-no-vec")
+ENDIF()
+
+
#
# gcc-4.8.1 has some problems with the constexpr "vertices_per_cell" in the
# definition of alternating_form_at_vertices.
--- /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.
+##
+## ---------------------------------------------------------------------
+
+
+#
+# CMakes Ninja generator is currently incompatible with everything but gcc
+# and clang.
+#
+# - Matthias Maier, 2013
+#
+
+IF( CMAKE_GENERATOR MATCHES "Ninja" AND NOT
+ ( CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
+ CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) )
+ MESSAGE(FATAL_ERROR "\n"
+ "Error!\n"
+ "The CMAKE_GENERATOR \"${CMAKE_GENERATOR}\" "
+ "currently only supports the GNU and Clang C++ compilers, but "
+ "\"${CMAKE_CXX_COMPILER_ID}\" was found.\n\n"
+ )
+ENDIF()
# DEAL_II_ADD_TEST(category test_name comparison_file [ARGN])
#
# This macro assumes that a source file "./tests/category/<test_name>.cc"
-# as well as the comparison file "./tests/category/<comparison_file>" is
-# available in the testsuite. The output of compiled source file is
-# compared against the file comparison file.
-#
-# [ARGN] is an optional list of additional output lines passed down to the
-# run_test.cmake script and printed at the beginning of the test output.
+# as well as the comparison file "<comparison_file>" is available in the
+# testsuite. The output of compiled source file is compared against the
+# file comparison file.
#
# This macro gets the following options from the comparison file name (have
# a look at the testsuite documentation for details):
-DTRGT=${_diff_target}
-DTEST=${_test_full}
-DEXPECT=${_expect}
- -DADDITIONAL_OUTPUT=${ARGN}
-DDEAL_II_BINARY_DIR=${CMAKE_BINARY_DIR}
-DGUARD_FILE=${CMAKE_CURRENT_BINARY_DIR}/${_target}/interrupt_guard.cc
-P ${DEAL_II_SOURCE_DIR}/cmake/scripts/run_test.cmake
# when compiling the not yet existent executable that is shared
# between the different tests.
#
- # Luckily CMake has a mechanism to force a test to be run when
+ # Luckily CMake has a mechanism to force a test to be run after
# another has finished (and both are scheduled):
#
IF(NOT "${_n_cpu}" STREQUAL "0")
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
IF(DEFINED OSX_CERTIFICATE_NAME)
- ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/${TARGET}.signed
+ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TARGET}.signed
COMMAND codesign -f -s ${OSX_CERTIFICATE_NAME} ${TARGET}
- COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/${TARGET}.signed
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TARGET}.signed
COMMENT "Digitally signing ${TARGET}"
DEPENDS ${TARGET}
VERBATIM
)
ADD_CUSTOM_TARGET(sign ALL
- DEPENDS ${CMAKE_BINARY_DIR}/${TARGET}.signed
+ DEPENDS ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TARGET}.signed
)
ADD_DEPENDENCIES(run sign)
ELSE()
SET(_define_test FALSE)
ENDIF()
+ #
+ # Respect compiler constraint:
+ #
+
+ STRING(REGEX MATCHALL
+ "compiler=[^=]*=(on|off|yes|no|true|false)" _matches ${_test}
+ )
+ FOREACH(_match ${_matches})
+ STRING(REGEX REPLACE
+ "^compiler=([^=]*)=(on|off|yes|no|true|false)$" "\\1"
+ _compiler ${_match}
+ )
+ STRING(REGEX MATCH "(on|off|yes|no|true|false)$" _boolean ${_match})
+
+ IF( ( "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}"
+ MATCHES "^${_compiler}"
+ AND NOT ${_boolean} )
+ OR ( NOT "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}"
+ MATCHES "^${_compiler}"
+ AND ${_boolean} ) )
+ SET(_define_test FALSE)
+ ENDIF()
+ ENDFOREACH()
+
#
# Query configuration and check whether we support it. Otherwise
# set _define_test to FALSE:
ENDIF()
ENDFOREACH()
- #
- # Respect TEST_OVERRIDE_LOCATION:
- #
-
- SET(_add_output)
- IF(EXISTS ${TEST_OVERRIDE_LOCATION}/${_category}/${_test})
- SET(_add_output
- "!!NOTE!! Comparison file overriden by ${TEST_OVERRIDE_LOCATION}/${_category}/${_test}"
- )
- SET(_comparison "${TEST_OVERRIDE_LOCATION}/${_category}/${_test}")
- ENDIF()
-
IF(_define_test)
STRING(REGEX REPLACE "\\..*" "" _test ${_test})
DEAL_II_ADD_TEST(${_category} ${_test} ${_comparison} ${_add_output})
# (return value 0)
# Possible values are CONFIGURE, BUILD, RUN, DIFF, PASSED
#
-# ADDITIONAL_OUTPUT - A list of additional output lines that should be printed
-#
# GUARD_FILE - used to detect a forced interruption of this script: On
# startup the backed up file ${GUARD_FILE}_bck is put back
# in place as ${GUARD_FILE} and on exit ${GUARD_FILE} is
MESSAGE("Test ${TEST}: ${_stage}")
-FOREACH(_line ${ADDITIONAL_OUTPUT})
- MESSAGE("Test ${TEST}: ${_line}")
-ENDFOREACH()
-
MESSAGE("=============================== OUTPUT BEGIN ===============================")
IF("${_stage}" STREQUAL "PASSED")
# #
########################################################################
-IF(NOT "${_branch}" STREQUAL "")
+IF("${_branch}" STREQUAL "")
+ #
+ # If we have no branch information, just assume we are on trunk:
+ #
+ SET_PROPERTY(GLOBAL PROPERTY SubProject "trunk")
+ELSE()
SET_PROPERTY(GLOBAL PROPERTY SubProject ${_branch})
ENDIF()
MESSAGE("-- Submission successful. Goodbye!")
ENDIF()
-# .oO( This script is freaky 593 lines long... )
+# .oO( This script is freaky 632 lines long... )
# Setup tests:
ADD_CUSTOM_TARGET(setup_tests)
+# Remove all tests:
+ADD_CUSTOM_TARGET(prune_tests)
+
# Regenerate tests (run "make rebuild_cache" in subprojects):
ADD_CUSTOM_TARGET(regen_tests
COMMAND ${CMAKE_COMMAND}
-- ${MAKEOPTS}
)
-# Remove all tests:
-ADD_CUSTOM_TARGET(prune_tests
- COMMAND ${CMAKE_COMMAND}
- --build ${CMAKE_BINARY_DIR}/tests --target prune_tests
- -- ${MAKEOPTS}
- )
-
MESSAGE(STATUS "Setup testsuite")
#
-# Setup the testsuite project: It is merely a wrapper around the individual
-# regen_tests_*, clean_tests_* and prune_tests_* targets.
-# down to it:
+# Provide custom targets to setup and prune the testsuite subproject:
#
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR}
- -DDEAL_II_BINARY_DIR=${CMAKE_BINARY_DIR}
-DTEST_DIR=${TEST_DIR}
${CMAKE_SOURCE_DIR}/tests
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tests
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
+ DIFF_DIR NUMDIFF_DIR TEST_DIFF TEST_OVERRIDE_LOCATION TEST_PICKUP_REGEX
TEST_TIME_LIMIT
)
# always undefine:
#
FOREACH(_category ${_categories})
- IF(EXISTS ${CMAKE_SOURCE_DIR}/${_category}/CMakeLists.txt)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/tests/${_category}/CMakeLists.txt)
SET(_category_dir ${CMAKE_SOURCE_DIR}/tests/${_category})
ELSEIF(EXISTS ${TEST_DIR}/${_category}/CMakeLists.txt)
SET(_category_dir ${TEST_DIR}/${_category})
)
ADD_DEPENDENCIES(setup_tests setup_tests_${_category})
+ ADD_CUSTOM_TARGET(prune_tests_${_category}
+ COMMAND ${CMAKE_COMMAND} -E remove_directory
+ ${CMAKE_BINARY_DIR}/tests/${_category}
+ )
+ ADD_DEPENDENCIES(prune_tests prune_tests_${_category})
+
FILE(APPEND ${CMAKE_BINARY_DIR}/tests/CTestTestfile.cmake
"SUBDIRS(${_category})\n"
)
flags or compiler support, please respect the following note
<pre>
-
- #
- # (./cmake/setup_compiler_flags.cmake)
- #
- # ####################
- # # FAT NOTE: #
- # ####################
- #
- # All configuration in setup_compiler_flags.cmake and
- # setup_compiler_flags_<compiler>.cmake shall ONLY modify:
- #
- # CMAKE_CXX_FLAGS
- # DEAL_II_CXX_FLAGS_DEBUG
- # DEAL_II_CXX_FLAGS_RELEASE
- # DEAL_II_LINKER_FLAGS
- # DEAL_II_LINKER_FLAGS_DEBUG
- # DEAL_II_LINKER_FLAGS_RELEASE
- #
- # All modifications shall be guarded with the ENABLE_IF_SUPPORTED
- # or ENABLE_IF_LINKS macro, e.g.
- #
- # ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-fpic")
- # ENABLE_IF_LINKS(DEAL_II_LINKER_FLAGS "-Wl,--as-needed")
- #
- # Compiler flags for platform dependent optimization (such as
- # -march=native) must always be guarded with
- # DEAL_II_ALLOW_PLATFORM_INTROSPECTION:
- #
- # IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
- # ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-march=native")
- # ENDIF()
- #
- # Checks for compiler features (such as C++11 support) and compiler
- # specific bugs that
- # - usually set up further configuration (such as preprocessor
- # definitions)
- # - disable a specific flag for a specific compiler version.
- #
- # belong the corresponding file:
- #
- # ./cmake/checks/check_01_compiler_features.cmake
- # ./cmake/checks/check_01_cpu_features.cmake
- # ./cmake/checks/check_01_cxx_features.cmake
- # ./cmake/checks/check_01_system_features.cmake
- # ./cmake/checks/check_02_compiler_bugs.cmake
- #
+#
+# (./cmake/setup_compiler_flags.cmake)
+#
+# ####################
+# # FAT NOTE: #
+# ####################
+#
+# All configuration in setup_compiler_flags.cmake and
+# setup_compiler_flags_<compiler>.cmake shall ONLY modify:
+#
+# CMAKE_CXX_FLAGS
+# DEAL_II_CXX_FLAGS_DEBUG
+# DEAL_II_CXX_FLAGS_RELEASE
+# DEAL_II_LINKER_FLAGS
+# DEAL_II_LINKER_FLAGS_DEBUG
+# DEAL_II_LINKER_FLAGS_RELEASE
+#
+# All modifications shall be guarded with the ENABLE_IF_SUPPORTED
+# or ENABLE_IF_LINKS macro, e.g.
+#
+# ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-fpic")
+# ENABLE_IF_LINKS(DEAL_II_LINKER_FLAGS "-Wl,--as-needed")
+#
+# Compiler flags for platform dependent optimization (such as
+# -march=native) must always be guarded with
+# DEAL_II_ALLOW_PLATFORM_INTROSPECTION:
+#
+# IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
+# ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-march=native")
+# ENDIF()
+#
+# Checks for compiler features (such as C++11 support) and compiler
+# specific bugs that
+# - usually set up further configuration (such as preprocessor
+# definitions)
+# - disable a specific flag for a specific compiler version.
+#
+# belong the corresponding file:
+#
+# ./cmake/checks/check_01_compiler_features.cmake
+# ./cmake/checks/check_01_cpu_features.cmake
+# ./cmake/checks/check_01_cxx_features.cmake
+# ./cmake/checks/check_01_system_features.cmake
+# ./cmake/checks/check_02_compiler_bugs.cmake
+#
</pre>
</ul>
</p>
there are:
<pre>
-
- ./cmake/checks/check_01_compiler_features.cmake
- - Search for support for compiler dependent features such as stack
- trace support, demangler support, etc.
-
- ./cmake/checks/check_01_cpu_features.cmake
- - Platform introspection for CPU features goes here and must be
- guarded with DEAL_II_ALLOW_PLATFORM_INTROSPECTION
+./cmake/checks/check_01_compiler_features.cmake
+ - Search for support for compiler dependent features such as stack
+ trace support, demangler support, etc.
- ./cmake/checks/check_01_cxx_features.cmake
- - Check for supported C++ language features such as sufficient C++11
- support
+./cmake/checks/check_01_cpu_features.cmake
+ - Platform introspection for CPU features goes here and must be
+ guarded with DEAL_II_ALLOW_PLATFORM_INTROSPECTION
- ./cmake/checks/check_01_system_features.cmake
- - Checks for specific platform (Linux/Darwin/CYGWIN/Windows..)
- features and support
+./cmake/checks/check_01_cxx_features.cmake
+ - Check for supported C++ language features such as sufficient C++11
+ support
- ./cmake/checks/check_02_compiler_bugs.cmake
- - Check for compiler bugs
+./cmake/checks/check_01_system_features.cmake
+ - Checks for specific platform (Linux/Darwin/CYGWIN/Windows..)
+ features and support
+./cmake/checks/check_02_compiler_bugs.cmake
+ - Check for compiler bugs
</pre>
<ul>
There are a number of readily available platform check macros:
<pre>
-
- CHECK_CXX_SOURCE_COMPILES(source variable)
- - Checks whether it is possible to compile _and_ link the code snippet
- <source>. If successful, variable is set to 1.
-
- CHECK_CXX_SOURCE_RUNS(source variable)
- - variable is set to 1 if <source> could be successfully compiled and
- linked and the resulting program ran and exited without error.
- Avoid this macro outside of a DEAL_II_ALLOW_PLATFORM_INTROSPECTION
- guard. A sensible fallback should be provided if the check cannot
- be run (e.g. when cross compiling).
-
- CHECK_CXX_COMPILER_BUG(source variable)
- - Inverts the logic of CHECK_CXX_SOURCE_COMPILES(), i.e. variable is
- set to 1 if it was not possible to compile and link <source>.
-
- CHECK_INCLUDE_FILE_CXX(header variable)
- - Check whether it is possible to compile and link a dummy program
- including <header>.
-
- CHECK_FUNCTION_EXISTS(function variable)
- - Check for the existence of a function prototype with name
- <function>. (Don't forget to specify the link libraries, see
- below.) Use CHECK_CXX_SYMBOL_EXISTS to search for C++ function
- definitions instead, if possible.
-
- CHECK_CXX_SYMBOL_EXISTS(symbol header_file variable)
- - Check for the existence of a symbol definition in the header_file
- as well as for the presence in the current link interface
- (Don't forget to specify the link libraries, see below.)
-
- CHECK_CXX_COMPILER_FLAG(flag variable)
- - Sets the variable to 1 if the compiler understands the flag.
-
+CHECK_CXX_SOURCE_COMPILES(source variable)
+ - Checks whether it is possible to compile _and_ link the code snippet
+ <source>. If successful, variable is set to 1.
+
+CHECK_CXX_SOURCE_RUNS(source variable)
+ - variable is set to 1 if <source> could be successfully compiled and
+ linked and the resulting program ran and exited without error.
+ Avoid this macro outside of a DEAL_II_ALLOW_PLATFORM_INTROSPECTION
+ guard. A sensible fallback should be provided if the check cannot
+ be run (e.g. when cross compiling).
+
+CHECK_CXX_COMPILER_BUG(source variable)
+ - Inverts the logic of CHECK_CXX_SOURCE_COMPILES(), i.e. variable is
+ set to 1 if it was not possible to compile and link <source>.
+
+CHECK_INCLUDE_FILE_CXX(header variable)
+ - Check whether it is possible to compile and link a dummy program
+ including <header>.
+
+CHECK_FUNCTION_EXISTS(function variable)
+ - Check for the existence of a function prototype with name
+ <function>. (Don't forget to specify the link libraries, see
+ below.) Use CHECK_CXX_SYMBOL_EXISTS to search for C++ function
+ definitions instead, if possible.
+
+CHECK_CXX_SYMBOL_EXISTS(symbol header_file variable)
+ - Check for the existence of a symbol definition in the header_file
+ as well as for the presence in the current link interface
+ (Don't forget to specify the link libraries, see below.)
+
+CHECK_CXX_COMPILER_FLAG(flag variable)
+ - Sets the variable to 1 if the compiler understands the flag.
</pre>
<li> Necessary compiler flags can easily set in the string variable
<code>CMAKE_REQUIRED_FLAGS</code>. There are two small macros
that do this job nicely:
-<pre>
-
- PUSH_TEST_FLAG("-Werror")
- CHECK_CXX_SOURCE_COMPILES(...)
- POP_TEST_FLAG()
+<pre class="cmake">
+PUSH_TEST_FLAG("-Werror")
+CHECK_CXX_SOURCE_COMPILES(...)
+POP_TEST_FLAG()
</pre>
<li> Necessary include directories and libraries necessary for
lists and later on reset <code>CMAKE_REQUIRED_*</code> (including
<code>CMAKE_REQUIRED_FLAGS</code>) to their default values:
-<pre>
-
- LIST(APPEND CMAKE_REQUIRED_INCLUDES <a list of includes>)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES <a list of libraries>)
- CHECK_CXX_SOURCE_COMPILES(...)
- RESET_CMAKE_REQUIRED()
+<pre class="cmake">
+LIST(APPEND CMAKE_REQUIRED_INCLUDES <a list of includes>)
+LIST(APPEND CMAKE_REQUIRED_LIBRARIES <a list of libraries>)
+CHECK_CXX_SOURCE_COMPILES(...)
+RESET_CMAKE_REQUIRED()
</pre>
</ul>
</p>
If successful, the following uncached variables might be set:
<pre>
-
- FEATURE_FOUND
- FEATURE_LIBRARIES
- FEATURE_INCLUDE_DIRS
- FEATURE_LINKER_FLAGS
-
- FEATURE_VERSION
- FEATURE_VERSION_MAJOR
- FEATURE_VERSION_MINOR
- FEATURE_VERSION_SUBMINOR
+FEATURE_FOUND
+FEATURE_LIBRARIES
+FEATURE_INCLUDE_DIRS
+FEATURE_LINKER_FLAGS
+
+FEATURE_VERSION
+FEATURE_VERSION_MAJOR
+FEATURE_VERSION_MINOR
+FEATURE_VERSION_SUBMINOR
</pre>
There are obviously valid exceptions from this rule, though.
A hint with <code>FEATURE_DIR</code> can be set up for
convenience. It is best to start the <code>Find</code> module by
-<pre>
-
- SET_IF_EMPTY(FEATURE_DIR "$ENV{FEATURE_DIR}")
+<pre class="cmake">
+SET_IF_EMPTY(FEATURE_DIR "$ENV{FEATURE_DIR}")
</pre>
and use <code>FEATURE_DIR</code> as a hint. If the external
library could be found, hide it via
<code>MARK_AS_ADVANCED</code>, if the external library could not
be found, set a cache value:
-<pre>
-
- SET(FEATURE_DIR "" CACHE PATH "An optional hint to a FEATURE directory")
+<pre class="cmake">
+SET(FEATURE_DIR "" CACHE PATH "An optional hint to a FEATURE directory")
</pre>
</ul>
- <a name="configure"></a>
- <h3> <code>./cmake/configure/configure_*.cmake</code> </h3>
-
+<a name="configure"></a>
+<h3> <code>./cmake/configure/configure_*.cmake</code> </h3>
+
<p>
The final step in the configuration phase is the setup of features
(which refer to external or bundled libraries
<acronym>deal.II</acronym> can optionally interface with.)
-
</p>
- <p>
- At bare minimum <code>configure_<feature>.cmake</code>
- file for a feature just consists of a call to the
- <code>CONFIGURE_FEATURE(<FEATURE>)</code> macro which is
- implemented in
- <code>./cmake/macros/macro_configure_feature.cmake</code>.
- In this case the corresponding <code>Find<FEATURE>.cmake</code>
- module is used to determine whether an external dependency can be
- resolved or not. Depending on the current state of
- <code>DEAL_II_WITH_<FEATURE></code> (see
- <a href="cmake.html#configurefeature">here</a>) the variables
- <pre>
-
- FEATURE_LIBRARIES
- FEATURE_INCLUDE_DIRS
- FEATURE_LINKER_FLAGS
- </pre>
- are appended to the set of <a href="#variables">global variables</a>
- and <code>DEAL_II_WITH_<FEATURE></code> is set to
- <code>TRUE</code>.
- </p>
-
- <p>
- It is possible to override this default behaviour with the following
- variables and macros (all of them are optional and will be replaced
- by an appropriate default action if unset):
+<p>
+ At bare minimum <code>configure_<feature>.cmake</code>
+ file for a feature just consists of a call to the
+ <code>CONFIGURE_FEATURE(<FEATURE>)</code> macro which is
+ implemented in
+ <code>./cmake/macros/macro_configure_feature.cmake</code>.
+ In this case the corresponding <code>Find<FEATURE>.cmake</code>
+ module is used to determine whether an external dependency can be
+ resolved or not. Depending on the current state of
+ <code>DEAL_II_WITH_<FEATURE></code> (see
+ <a href="cmake.html#configurefeature">here</a>) the variables
+<pre>
+FEATURE_LIBRARIES
+FEATURE_INCLUDE_DIRS
+FEATURE_LINKER_FLAGS
+</pre>
+ are appended to the set of <a href="#variables">global variables</a>
+ and <code>DEAL_II_WITH_<FEATURE></code> is set to
+ <code>TRUE</code>.
+</p>
+
+<p>
+ It is possible to override this default behaviour with the following
+ variables and macros (all of them are optional and will be replaced
+ by an appropriate default action if unset):
+ <ul>
+ <li>
+ <code><FEATURE></code> means all caps,
+ <code><feature></code> means all lowercase
+
+ <li>
+ In <code>./cmake/configure/configure_<feature>.cmake</code>:
+<pre>
+FEATURE_<FEATURE>_DEPENDS (a variable)
+ - a variable which contains an optional list of other features
+ this feature depends on (and which have to be enabled for this feature
+ to work.) The features must be given with the full option toggle:
+ DEAL_II_WITH_[...]
+
+FEATURE_<FEATURE>_FIND_EXTERNAL(var) (a macro)
+ - which should set var to TRUE if all dependencies for the feature are
+ fulfilled. In this case all necessary variables for
+ FEATURE_<FEATURE>_CONFIGURE_EXTERNAL must be set.
+ Otherwise var should remain unset.
+ If this macro is undefined, FIND_PACKAGE(<FEATURES>) is
+ called directly instead.
+
+FEATURE_<FEATURE>_CONFIGURE_EXTERNAL() (a macro)
+ - which should setup all necessary configuration for the feature with
+ external dependencies. If something goes wrong this macro must
+ issue a FATAL_ERROR.
+ If this macro is undefined, the information provided in
+ <FEATURES>_LIBRARIES, <FEATURES>_INCLUDE_DIRS and
+ <FEATURES>_LINKER_FLAGS is used for the build.
+
+FEATURE_<FEATURE>_CONFIGURE_BUNDLED() (a macro)
+ - which should setup all necessary configuration for the feature with
+ bundled source dependencies. If something goes wrong this macro must
+ issue a FATAL_ERROR.
+
+FEATURE_<FEATURE>_ERROR_MESSAGE() (macro)
+ - which should print a meaningful error message (with FATAL_ERROR) for
+ the case that no external library was found (and bundled is not
+ allowed to be used.) If not defined, a suitable default error message
+ will be printed.
+</pre>
+
+ <li>
+ In <code>./bundled/CMakeLists.txt</code>:
+<pre>
+FEATURE_<FEATURE>_HAVE_BUNDLED (a boolean)
+ - which should either be set to TRUE if all necessary libraries of the
+ features comes bundled with deal.II and hence can be supported
+ without external dependencies, or unset.
+
+DEAL_II_FORCE_BUNDLED_<FEATURE> (an option)
+ - If <feature> can be set up by bundled libraries, this
+ configuration option must be present to force a use of bundled
+ dependencies
+</pre>
+
+ <li>
+ Furthermore, if
+ <code>FEATURE_<FEATURE>_BUNDLED_CONFIGURED</code> is set to
+ <code>TRUE</code> the file <code>./bundled/CMakeLists.txt</code>
+ must compile and install the bundled package appropriately.
+ </ul>
+</p>
+
+
+
+<a name="variables"></a>
+<h3> Global variables controlling the build process </h3>
+
+<p>
+ The following list describes all global variables controlling the
+ build process and the visibility associated with it (internal use for
+ compiling deal.Ii, externally used variables will get exported in
+ deal.IIConfig.cmake). Lists should be manipulated with
+ <code>LIST(APPEND ...)</code>, flags with <code>ADD_FLAGS(...)</code>
+ (or if it is necessary to guard them with
+ <code>ENABLE_IF_SUPPORTED(...)</code>.)
+ <ul>
+ <li>
+ The general (internal) logic for variables applies:
<ul>
- <li>
- <code><FEATURE></code> means all caps,
- <code><feature></code> means all lowercase
-
- <li>
- In <code>./cmake/configure/configure_<feature>.cmake</code>:
- <pre>
-
- FEATURE_<FEATURE>_DEPENDS (a variable)
- - a variable which contains an optional list of other features
- this feature depends on (and which have to be enabled for this feature
- to work.) The features must be given with the full option toggle:
- DEAL_II_WITH_[...]
-
- FEATURE_<FEATURE>_FIND_EXTERNAL(var) (a macro)
- - which should set var to TRUE if all dependencies for the feature are
- fulfilled. In this case all necessary variables for
- FEATURE_<FEATURE>_CONFIGURE_EXTERNAL must be set.
- Otherwise var should remain unset.
- If this macro is undefined, FIND_PACKAGE(<FEATURES>) is
- called directly instead.
-
- FEATURE_<FEATURE>_CONFIGURE_EXTERNAL() (a macro)
- - which should setup all necessary configuration for the feature with
- external dependencies. If something goes wrong this macro must
- issue a FATAL_ERROR.
- If this macro is undefined, the information provided in
- <FEATURES>_LIBRARIES, <FEATURES>_INCLUDE_DIRS and
- <FEATURES>_LINKER_FLAGS is used for the build.
-
- FEATURE_<FEATURE>_CONFIGURE_BUNDLED() (a macro)
- - which should setup all necessary configuration for the feature with
- bundled source dependencies. If something goes wrong this macro must
- issue a FATAL_ERROR.
-
- FEATURE_<FEATURE>_ERROR_MESSAGE() (macro)
- - which should print a meaningful error message (with FATAL_ERROR) for
- the case that no external library was found (and bundled is not
- allowed to be used.) If not defined, a suitable default error message
- will be printed.
- </pre>
-
- <li>
- In <code>./bundled/CMakeLists.txt</code>:
- <pre>
-
- FEATURE_<FEATURE>_HAVE_BUNDLED (a boolean)
- - which should either be set to TRUE if all necessary libraries of the
- features comes bundled with deal.II and hence can be supported
- without external dependencies, or unset.
-
- DEAL_II_FORCE_BUNDLED_<FEATURE> (an option)
- - If <feature> can be set up by bundled libraries, this
- configuration option must be present to force a use of bundled
- dependencies
- </pre>
-
- <li>
- Furthermore, if
- <code>FEATURE_<FEATURE>_BUNDLED_CONFIGURED</code> is set to
- <code>TRUE</code> the file <code>./bundled/CMakeLists.txt</code>
- must compile and install the bundled package appropriately.
+ <li>A variable name without <code>_DEBUG</code> or
+ <code>_RELEASE</code>: Used for all targets
+ <li> <code><...>_DEBUG</code>: <i>additionally</i> used for debug targets
+ <li> <code><...>_RELEASE</code>: <i>additionally</i> used for release targets
</ul>
- </p>
-
+ <li>
+ For internal use, for setting necessary linker flags for the deal.II library:
+ <ul>
+ <li> <code>DEAL_II_LINKER_FLAGS</code>
+ <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
+ <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
+ </ul>
+ <li>
+ For internal use, for setting necessary compiler flags, e.g.
+ <code>-std=c++11</code> (if available):
+ <ul>
+ <li> <code>CMAKE_CXX_FLAGS</code>
+ <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
+ <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
+ </ul>
+ <li>
+ For internal use, for setting necessary include dirs for the compilation of the
+ <acronym>deal.II</acronym> library:
+ <ul>
+ <li> <code>INCLUDE_DIRECTORIES(...)</code>
+ </ul>
- <a name="variables"></a>
- <h3> Global variables controlling the build process </h3>
+ <li>
+ For internal use, for setting necessary preprocessor definitions
+ (<code>-D<...></code>) for the compilation of the
+ deal.II library:
+ <ul>
+ <li> <code>DEAL_II_DEFINITIONS</code>
+ <li> <code>DEAL_II_DEFINITIONS_DEBUG</code>
+ <li> <code>DEAL_II_DEFINITIONS_RELEASE</code>
+ </ul>
- <p>
- The following list describes all global variables controlling the
- build process and the visibility associated with it (internal use for
- compiling deal.Ii, externally used variables will get exported in
- deal.IIConfig.cmake). Lists should be manipulated with
- <code>LIST(APPEND ...)</code>, flags with <code>ADD_FLAGS(...)</code>
- (or if it is necessary to guard them with
- <code>ENABLE_IF_SUPPORTED(...)</code>.)
+ <li>
+ For internal and external use, used to keep track of external
+ libraries, the <acronym>deal.II</acronym> library and user
+ programs have to be linked against:
<ul>
- <li>
- The general (internal) logic for variables applies:
- <ul>
- <li>A variable name without <code>_DEBUG</code> or
- <code>_RELEASE</code>: Used for all targets
- <li> <code><...>_DEBUG</code>: <i>additionally</i> used for debug targets
- <li> <code><...>_RELEASE</code>: <i>additionally</i> used for release targets
- </ul>
-
- <li>
- For internal use, for setting necessary linker flags for the deal.II library:
- <ul>
- <li> <code>DEAL_II_LINKER_FLAGS</code>
- <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
- <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
- </ul>
-
- <li>
- For internal use, for setting necessary compiler flags, e.g.
- <code>-std=c++11</code> (if available):
- <ul>
- <li> <code>CMAKE_CXX_FLAGS</code>
- <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
- <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
- </ul>
-
- <li>
- For internal use, for setting necessary include dirs for the compilation of the
- <acronym>deal.II</acronym> library:
- <ul>
- <li> <code>INCLUDE_DIRECTORIES(...)</code>
- </ul>
-
- <li>
- For internal use, for setting necessary preprocessor definitions
- (<code>-D<...></code>) for the compilation of the
- deal.II library:
- <ul>
- <li> <code>DEAL_II_DEFINITIONS</code>
- <li> <code>DEAL_II_DEFINITIONS_DEBUG</code>
- <li> <code>DEAL_II_DEFINITIONS_RELEASE</code>
- </ul>
-
- <li>
- For internal and external use, used to keep track of external
- libraries, the <acronym>deal.II</acronym> library and user
- programs have to be linked against:
- <ul>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES</code>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES_DEBUG</code>
- <li> <code>DEAL_II_EXTERNAL_LIBRARIES_RELEASE</code>
- </ul>
-
- <li>
- For external use, used to keep track of external preprocessor
- definitions, necessary for the compilation of user programs:
- <ul>
- <li> <code>DEAL_II_USER_DEFINITIONS</code>
- <li> <code>DEAL_II_USER_DEFINITIONS_DEBUG</code>
- <li> <code>DEAL_II_USER_DEFINITIONS_RELEASE</code>
- </ul>
-
- <li>
- Used to keep track of external include dirs, necessary for the
- compilation of user programs:
- <ul>
- <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
- </ul>
+ <li> <code>DEAL_II_EXTERNAL_LIBRARIES</code>
+ <li> <code>DEAL_II_EXTERNAL_LIBRARIES_DEBUG</code>
+ <li> <code>DEAL_II_EXTERNAL_LIBRARIES_RELEASE</code>
</ul>
- </p>
-
- <h2>Target definition and installation</h2>
- <a name="config.h.in"></a>
- <h3> <code>./include/deal.II/base/config.h.in</code> </h3>
+ <li>
+ For external use, used to keep track of external preprocessor
+ definitions, necessary for the compilation of user programs:
+ <ul>
+ <li> <code>DEAL_II_USER_DEFINITIONS</code>
+ <li> <code>DEAL_II_USER_DEFINITIONS_DEBUG</code>
+ <li> <code>DEAL_II_USER_DEFINITIONS_RELEASE</code>
+ </ul>
- In contrast to autoconf there is no intermediate step any more that
- automatically generates config.h.in. The setup in this file has to be
- done by hand. Please note:
+ <li>
+ Used to keep track of external include dirs, necessary for the
+ compilation of user programs:
<ul>
- <li> <code>config.h.in</code> should only contain a minimum of
- necessary compile definitions to avoid unnecessary recompilation if
- configuration changes.
- <li> Definition toggles in <code>config.h.in</code> should have a
- prominent comment explaining it and should be grouped by file
- exporting the definition.
+ <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
</ul>
+ </ul>
+</p>
+
+
+<h2>Target definition and installation</h2>
+<a name="config.h.in"></a>
+<h3> <code>./include/deal.II/base/config.h.in</code> </h3>
+
+In contrast to autoconf there is no intermediate step any more that
+automatically generates config.h.in. The setup in this file has to be
+done by hand. Please note:
+ <ul>
+ <li> <code>config.h.in</code> should only contain a minimum of
+ necessary compile definitions to avoid unnecessary recompilation if
+ configuration changes.
+ <li> Definition toggles in <code>config.h.in</code> should have a
+ prominent comment explaining it and should be grouped by file
+ exporting the definition.
+ </ul>
+
+<a name="source"></a>
+<h3><code>./source/CMakeLists.txt</code></h3>
+
+<p>
+ All parts of the library are organized into logical object libraries
+ with their respective sources lying under
+ <code>./source/<foo></code>, or
+ <code>./bundled/<foo>/<...></code>. The actual setup of
+ an object library happens within that subdirectories with the help of
+ two macros:
+<pre class="cmake">
+#
+# Glob for all header files associated with the object target:
+# As this list is only for cosmetic reasons, so that associated header
+# files show up in IDEs, we don't manage an explicit list (with the
+# trade-off to have to run "make rebuild_cache" when a new header file
+# emerges...)
+#
+FILE(GLOB _header
+ ${CMAKE_SOURCE_DIR}/include/deal.II/dofs/*.h
+ )
+
+#
+# A list of source files forming the object target:
+#
+SET(_src
+ ...
+ dof_tools.cc
+ )
+
+#
+# A list of instantiations that must be expanded:
+#
+SET(_inst
+ ...
+ dof_tools.inst.in
+ )
+
+#
+# The following macro will set up an obj_dofs.debug and
+# obj_dofs.release target with appropriate compile flags and
+# definitions for a simultaneous build of debug and release library.
+# Furthermore, the object name will be stored in
+# ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_(debug/release)
+# so that it is available in global scope.
+#
+# Header files and instatiation files (${_header}, ${_inst}) are added
+# for cosmetic reasons, so that they show up in IDEs.
+#
+DEAL_II_ADD_LIBRARY(obj_dofs OBJECT ${_src} ${_header} ${_inst})
+
+#
+# This macro will set up an obj_dofs.inst target for expanding all
+# files listed in ${inst_in_files}. Appropriate target dependencies
+# will be added to obj_dofs.debug and obj_dofs.release.
+#
+EXPAND_INSTANTIATIONS(obj_dofs "${inst_in_files}")
+</pre>
+</p>
+
+<p>
+ Later, all object targets are collected in
+ <code>./source/CMakeLists.txt</code> to define the actual debug and
+ releases libraries. For further details, see
+ <code>./source/CMakelists.txt</code> and
+ <code>./cmake/macros/macro_deal_ii_add_library.cmake</code>.
+</p>
+
+<a name="projectconfig"></a>
+<h3><code>./cmake/config/CMakeLists.txt</code></h3>
+
+<p>
+ The final bits of configuration happens in
+ <code>./cmake/config/CMakeLists.txt</code> where the templates for
+ the project configuration <code>deal.IIConfig.cmake</code> and the
+ compatibility file <code>Make.global_options</code> get expanded.
+ Furthermore, the configuration for the template expansion mechanism
+ resides under <code>./cmake/config/template_arguments.in</code>.
+</p>
+
+<hr />
+<address>
+ <a href="../authors.html" target="body">The deal.II Authors</a>
+ $Date$
+</address>
+<div class="right">
+ <a href="http://validator.w3.org/check?uri=referer" target="_top">
+ <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
+ <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
+</div>
- <a name="source"></a>
- <h3><code>./source/CMakeLists.txt</code></h3>
-
- <p>
- All parts of the library are organized into logical object libraries
- with their respective sources lying under
- <code>./source/<foo></code>, or
- <code>./bundled/<foo>/<...></code>. The actual setup of
- an object library happens within that subdirectories with the help of
- two macros:
- <pre>
-
- #
- # Glob for all header files associated with the object target:
- # As this list is only for cosmetic reasons, so that associated header
- # files show up in IDEs, we don't manage an explicit list (with the
- # trade-off to have to run "make rebuild_cache" when a new header file
- # emerges...)
- #
- FILE(GLOB _header
- ${CMAKE_SOURCE_DIR}/include/deal.II/dofs/*.h
- )
-
- #
- # A list of source files forming the object target:
- #
- SET(_src
- ...
- dof_tools.cc
- )
-
- #
- # A list of instantiations that must be expanded:
- #
- SET(_inst
- ...
- dof_tools.inst.in
- )
-
- #
- # The following macro will set up an obj_dofs.debug and
- # obj_dofs.release target with appropriate compile flags and
- # definitions for a simultaneous build of debug and release library.
- # Furthermore, the object name will be stored in
- # ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_(debug/release)
- # so that it is available in global scope.
- #
- # Header files and instatiation files (${_header}, ${_inst}) are added
- # for cosmetic reasons, so that they show up in IDEs.
- #
- DEAL_II_ADD_LIBRARY(obj_dofs OBJECT ${_src} ${_header} ${_inst})
-
- #
- # This macro will set up an obj_dofs.inst target for expanding all
- # files listed in ${inst_in_files}. Appropriate target dependencies
- # will be added to obj_dofs.debug and obj_dofs.release.
- #
- EXPAND_INSTANTIATIONS(obj_dofs "${inst_in_files}")
- </pre>
- </p>
-
- <p>
- Later, all object targets are collected in
- <code>./source/CMakeLists.txt</code> to define the actual debug and
- releases libraries. For further details, see
- <code>./source/CMakelists.txt</code> and
- <code>./cmake/macros/macro_deal_ii_add_library.cmake</code>.
- </p>
-
- <a name="projectconfig"></a>
- <h3><code>./cmake/config/CMakeLists.txt</code></h3>
-
- <p>
- The final bits of configuration happens in
- <code>./cmake/config/CMakeLists.txt</code> where the templates for
- the project configuration <code>deal.IIConfig.cmake</code> and the
- compatibility file <code>Make.global_options</code> get expanded.
- Furthermore, the configuration for the template expansion mechanism
- resides under <code>./cmake/config/template_arguments.in</code>.
- </p>
-
- <hr />
- <address>
- <a href="../authors.html" target="body">The deal.II Authors</a>
- $Date$
- </address>
- <div class="right">
- <a href="http://validator.w3.org/check?uri=referer" target="_top">
- <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
- <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
- </div>
-
- </body>
+</body>
</html>
To start porting for an unkown compiler, specify
<code>-DDEAL_II_SETUP_DEFAULT_COMPILER_FLAGS=OFF</code> and set all
necessary compiler flags by hand via
- <pre>
-
- CMAKE_CXX_FLAGS - used during all builds
- DEAL_II_CXX_FLAGS_DEBUG - additional flags for the debug library
- DEAL_II_CXX_FLAGS_RELEASE - additional flags for the release library
- </pre>
+<pre>
+CMAKE_CXX_FLAGS - used during all builds
+DEAL_II_CXX_FLAGS_DEBUG - additional flags for the debug library
+DEAL_II_CXX_FLAGS_RELEASE - additional flags for the release library
+</pre>
After that try to compile the library with minimal external
dependencies (<code>-DDEAL_II_ALLOW_AUTODETECTION=OFF</code>, for
further information see the <a href="cmake.html">deal.II CMake
<li>
For adding permanent support for the unknown compiler to the
build system, have a look at
- <pre>
-
- cmake/setup_compiler_flags.cmake
- cmake/setup_compiler_flags_gnu.cmake
- cmake/setup_compiler_flags_icc.cmake
- </pre>
+<pre>
+cmake/setup_compiler_flags.cmake
+cmake/setup_compiler_flags_gnu.cmake
+cmake/setup_compiler_flags_icc.cmake
+</pre>
Patches are highly welcome! See <a href="../mail.html">here</a>
for information on how to get in contact with us.
<li>
You might want to have a look at
- <pre>
-
- cmake/checks/check_for_compiler_bugs.cmake
- cmake/checks/check_for_compiler_features.cmake
- cmake/checks/check_for_cxx_features.cmake
- include/deal.II/base/config.h.in
- </pre>
+<pre>
+cmake/checks/check_01_for_compiler_features.cmake
+cmake/checks/check_01_for_cxx_features.cmake
+cmake/checks/check_03_for_compiler_bugs.cmake
+include/deal.II/base/config.h.in
+</pre>
to see how compiler specific checks are done.
</ul>
</p>
and Windows and throw a compile time error on other platforms.
<li>
Have a look at
- <pre>
-
- cmake/checks/check_for_compiler_bugs.cmake
- cmake/checks/check_for_compiler_features.cmake
- cmake/checks/check_for_cxx_features.cmake
- cmake/checks/check_for_system_features.cmake
- include/deal.II/base/config.h.in
- </pre>
+<pre>
+cmake/checks/check_for_compiler_bugs.cmake
+cmake/checks/check_for_compiler_features.cmake
+cmake/checks/check_for_cxx_features.cmake
+cmake/checks/check_for_system_features.cmake
+include/deal.II/base/config.h.in
+</pre>
to see how platform and compiler specific checks are done.
<li>
Of course, we would be happy to hear about the changes you made
(or for for
<a href="Toolchain-x86_64-w64-mingw32.sample">Windows64 using MinGW</a>).
After that invoke <code>cmake</code> with something like:
- <pre>
-
- cmake -DCMAKE_TOOLCHAIN_FILE=<...>/Toolchain.sample
- -DDEAL_II_FORCE_BUNDLED_BOOST=ON
- -DDEAL_II_ALLOW_AUTODETECTION=OFF
- ../deal.II
- </pre>
+<pre>
+$ cmake -DCMAKE_TOOLCHAIN_FILE=<...>/Toolchain.sample \
+ -DDEAL_II_FORCE_BUNDLED_BOOST=ON \
+ -DDEAL_II_ALLOW_AUTODETECTION=OFF \
+ ../deal.II
+</pre>
where <code>CMAKE_TOOLCHAIN_FILE</code> points to the toolchain file.
The remaining configuration can be adjusted at will, see <a
href="cmake.html">the documentation</a>.
<ol>
<li> Create the branch using
- <pre>
- svn copy https://svn.dealii.org/trunk/ https://svn.dealii.org/branches/new-branch-name
- </pre>
+<pre>
+$ svn copy https://svn.dealii.org/trunk/ https://svn.dealii.org/branches/new-branch-name
+</pre>
<li> Either check out the new branch or switch your working copy by
- <pre>
- svn switch https://svn.dealii.org/branches/new-branch-name
- </pre>
+<pre>
+$ svn switch https://svn.dealii.org/branches/new-branch-name
+</pre>
This command assumes you are in the top level directory, the one
containing <tt>deal.II</tt> and <tt>tests</tt>
<li> After some development of the branch, if you want to merge changes
that have been made on mainline in the meantime, you can use this command:
- <pre>
-
- svn merge ^/trunk
- </pre>
+<pre>
+$ svn merge ^/trunk
+</pre>
This command will only run if you have no local changes in your working
directory for the branch, and will modify all of your files by merging
the changes made on mainline. If there are no conflicts that need to be
<li><a href="#layout">Testsuite development</a></li>
<ol>
<li><a href="#layoutgeneral">General layout</a></li>
- <li><a href="#restrictbuild">Restricting tests for build configurations</a></li>
- <li><a href="#restrictfeature">Restricting tests for feature configurations</a></li>
+ <li><a href="#restrictcompiler">Restricting tests to specific compiler and compiler versions</a></li>
+ <li><a href="#restrictbuild">Restricting tests to build configurations</a></li>
+ <li><a href="#restrictfeature">Restricting tests to feature configurations</a></li>
<li><a href="#mpi">Running tests with MPI</a></li>
<li><a href="#binary">Tests with binary output</a></li>
<li><a href="#expect">Changing condition for success</a></li>
<p>
If you're impatient, use the following commands:
- <pre>
-
- $ mkdir new_directory
- $ cd new_directory
- $ svn checkout https://svn.dealii.org/trunk .
- $ mkdir build
- $ cd build
- $ cmake ../deal.II
- $ make -j16
- $ make -j16 setup_tests
- $ ctest -j16
- </pre>
+<pre>
+$ mkdir new_directory
+$ cd new_directory
+$ svn checkout https://svn.dealii.org/trunk .
+$ mkdir build
+$ cd build
+$ cmake ../deal.II
+$ make -j16
+$ make -j16 setup_tests
+$ ctest -j16
+</pre>
The exact meaning of all of these commands will be explained in much
greater detail below.
</p>
To download the testsuite, check it out from the subversion repository,
along with deal.II. To this end, go to an empty directory where you
want to test deal.II and do this:
- <pre>
-
- $ svn checkout https://svn.dealii.org/trunk .
- </pre>
+<pre>
+$ svn checkout https://svn.dealii.org/trunk .
+</pre>
(The period at the end puts everything from under <code>trunk/</code>
into the current directory, rather than creating a
new <code>trunk/</code> directory.) You will then have
two folders:
- <pre>
-
- ./deal.II
- ./tests
- </pre>
+<pre>
+./deal.II
+./tests
+</pre>
</p>
<p>
(<code>../tests</code>). If your test directory is at a different
location you have to hint during configuration by specifying
<code>TEST_DIR</code>:
- <pre>
-
- $ cmake -DTEST_DIR=<...>
- </pre>
+<pre>
+$ cmake -DTEST_DIR=<...>
+</pre>
</p>
<a name="setupconfigure"></a>
To enable the testsuite, configure and build deal.II in a build
directory as normal (installation is not necessary). After that you
can setup the testsuite via the "setup_tests" target:s
- <pre>
-
- $ make setup_tests
- </pre>
+<pre>
+$ make setup_tests
+</pre>
This will set up all tests supported by the current configuration.
The testsuite can now be run in the current <i>build directory</i> as
described below.
<p>
Setup can be fine-tuned using the following commands:
- <pre>
-
- $ make regen_tests - reruns configure stage in every testsuite subproject
+<pre>
+$ make regen_tests - reruns configure stage in every testsuite subproject
- $ make clean_tests - runs the 'clean' target in every testsuite subproject
+$ make clean_tests - runs the 'clean' target in every testsuite subproject
- $ make prune_tests - removes all testsuite subprojects
- </pre>
+$ make prune_tests - removes all testsuite subprojects
+</pre>
<p>
In addition, when setting up the testsuite, the following environment
variables can be used to override default behavior when
calling <code>make setup_tests</code>:
- <pre>
+<pre>
+TEST_DIFF
+ - The diff tool and command line to use for comparison. If numdiff is
+ available it defaults to "numdiff -a 1e-6 -q", otherwise plain diff
+ is used.
- TEST_DIFF
- - The diff tool and command line to use for comparison. If numdiff is
- available it defaults to "numdiff -a 1e-6 -q", otherwise plain diff
- is used.
+TEST_TIME_LIMIT
+ - The time limit (in seconds) a single test is allowed to take. Defaults
+ to 180 seconds
- TEST_TIME_LIMIT
- - The time limit (in seconds) a single test is allowed to take. Defaults
- to 180 seconds
-
- TEST_PICKUP_REGEX
- - A regular expression to select only a subset of tests during setup.
- An empty string is interpreted as a catchall (this is the default).
-
- TEST_OVERRIDE_LOCATION
- - 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.
- </pre>
+TEST_PICKUP_REGEX
+ - A regular expression to select only a subset of tests during setup.
+ An empty string is interpreted as a catchall (this is the default).
+</pre>
</p>
<a name="run"></a>
<p>
The testsuite can now be run in the <i>build directory</i> via
- <pre>
-
- $ ctest [-j N]
- </pre>
+<pre>
+$ ctest [-j N]
+</pre>
Here, <code>N</code> is the number of concurrent tests that should be
run, in the same way as you can say <code>make -jN</code>. The testsuite
is huge and will need around 12h on current computers
If you only want to run a subset of tests
matching a regular expression, or if you want to exclude tests matching
a regular expression, you can use
- <pre>
-
- $ ctest [-j N] -R '<positive regular expression>'
- $ ctest [-j N] -E '<negative regular expression>'
- </pre>
+<pre>
+$ ctest [-j N] -R '<positive regular expression>'
+$ ctest [-j N] -E '<negative regular expression>'
+</pre>
</p>
<p>
<p>
A typical output of a <code>ctest</code> invocation looks like:
- <pre>
-
- $ ctest -j4 -R "base/thread_validity"
- Test project /tmp/trunk/build
- Start 747: base/thread_validity_01.debug
- Start 748: base/thread_validity_01.release
- Start 775: base/thread_validity_05.debug
- Start 776: base/thread_validity_05.release
- 1/24 Test #776: base/thread_validity_05.release ... Passed 1.89 sec
- 2/24 Test #748: base/thread_validity_01.release ... Passed 1.89 sec
- Start 839: base/thread_validity_03.debug
- Start 840: base/thread_validity_03.release
- 3/24 Test #747: base/thread_validity_01.debug ..... Passed 2.68 sec
- [...]
- Start 1077: base/thread_validity_08.debug
- Start 1078: base/thread_validity_08.release
- 16/24 Test #1078: base/thread_validity_08.release ...***Failed 2.86 sec
- 18/24 Test #1077: base/thread_validity_08.debug .....***Failed 3.97 sec
- [...]
-
- 92% tests passed, 2 tests failed out of 24
-
- Total Test time (real) = 20.43 sec
-
- The following tests FAILED:
- 1077 - base/thread_validity_08.debug (Failed)
- 1078 - base/thread_validity_08.release (Failed)
- Errors while running CTest
- </pre>
+<pre>
+$ ctest -j4 -R "base/thread_validity"
+Test project /tmp/trunk/build
+ Start 747: base/thread_validity_01.debug
+ Start 748: base/thread_validity_01.release
+ Start 775: base/thread_validity_05.debug
+ Start 776: base/thread_validity_05.release
+ 1/24 Test #776: base/thread_validity_05.release ... Passed 1.89 sec
+ 2/24 Test #748: base/thread_validity_01.release ... Passed 1.89 sec
+ Start 839: base/thread_validity_03.debug
+ Start 840: base/thread_validity_03.release
+ 3/24 Test #747: base/thread_validity_01.debug ..... Passed 2.68 sec
+[...]
+ Start 1077: base/thread_validity_08.debug
+ Start 1078: base/thread_validity_08.release
+16/24 Test #1078: base/thread_validity_08.release ...***Failed 2.86 sec
+18/24 Test #1077: base/thread_validity_08.debug .....***Failed 3.97 sec
+[...]
+
+92% tests passed, 2 tests failed out of 24
+
+Total Test time (real) = 20.43 sec
+
+The following tests FAILED:
+ 1077 - base/thread_validity_08.debug (Failed)
+ 1078 - base/thread_validity_08.release (Failed)
+Errors while running CTest
+</pre>
If a test failed (like <code>base/thread_validity_08.debug</code> in above
example output), you might want to find out what exactly went wrong. To
this end, you can search
through <code>Testing/Temporary/LastTest.log</code> for the exact output
of the test, or you can rerun this one test, specifying <code>-V</code>
to select verbose output of tests:
- <pre>
-
- $ ctest -V -R "base/thread_validity_08.debug"
- [...]
- test 1077
- Start 1077: base/thread_validity_08.debug
-
- 1077: Test command: [...]
- 1077: Test timeout computed to be: 600
- 1077: Test base/thread_validity_08.debug: RUN
- 1077: =============================== OUTPUT BEGIN ===============================
- 1077: Built target thread_validity_08.debug
- 1077: Generating thread_validity_08.debug/output
- 1077: terminate called without an active exception
- 1077: /bin/sh: line 1: 18030 Aborted [...]/thread_validity_08.debug
- 1077: base/thread_validity_08.debug: BUILD successful.
- 1077: base/thread_validity_08.debug: RUN failed. Output:
- 1077: DEAL::OK.
- 1077: gmake[3]: *** [thread_validity_08.debug/output] Error 1
- 1077: gmake[2]: *** [CMakeFiles/thread_validity_08.debug.diff.dir/all] Error 2
- 1077: gmake[1]: *** [CMakeFiles/thread_validity_08.debug.diff.dir/rule] Error 2
- 1077: gmake: *** [thread_validity_08.debug.diff] Error 2
- 1077:
- 1077:
- 1077: base/thread_validity_08.debug: ****** RUN failed *******
- 1077:
- 1077: =============================== OUTPUT END ===============================
- </pre>
+<pre>
+$ ctest -V -R "base/thread_validity_08.debug"
+[...]
+test 1077
+ Start 1077: base/thread_validity_08.debug
+
+1077: Test command: [...]
+1077: Test timeout computed to be: 600
+1077: Test base/thread_validity_08.debug: RUN
+1077: =============================== OUTPUT BEGIN ===============================
+1077: Built target thread_validity_08.debug
+1077: Generating thread_validity_08.debug/output
+1077: terminate called without an active exception
+1077: /bin/sh: line 1: 18030 Aborted [...]/thread_validity_08.debug
+1077: base/thread_validity_08.debug: BUILD successful.
+1077: base/thread_validity_08.debug: RUN failed. Output:
+1077: DEAL::OK.
+1077: gmake[3]: *** [thread_validity_08.debug/output] Error 1
+1077: gmake[2]: *** [CMakeFiles/thread_validity_08.debug.diff.dir/all] Error 2
+1077: gmake[1]: *** [CMakeFiles/thread_validity_08.debug.diff.dir/rule] Error 2
+1077: gmake: *** [thread_validity_08.debug.diff] Error 2
+1077:
+1077:
+1077: base/thread_validity_08.debug: ****** RUN failed *******
+1077:
+1077: =============================== OUTPUT END ===============================
+</pre>
So this specific test aborted in the <code>RUN</code> stage.
</p>
The general output for a successful test <code><test></code> in
category <code><category></code> for build type
<code><build></code> is
- <pre>
-
- xx: Test <category>/<test>.<build>: PASSED
- xx: =============================== OUTPUT BEGIN ===============================
- xx: [...]
- xx: <category>/<test>.<build>: PASSED.
- xx: =============================== OUTPUT END ===============================
- </pre>
+<pre>
+xx: Test <category>/<test>.<build>: PASSED
+xx: =============================== OUTPUT BEGIN ===============================
+xx: [...]
+xx: <category>/<test>.<build>: PASSED.
+xx: =============================== OUTPUT END ===============================
+</pre>
And for a test that fails in stage <code><stage></code>:
- <pre>
-
- xx: Test <category>/<test>.<build>: <stage>
- xx: =============================== OUTPUT BEGIN ===============================
- xx: [...]
- xx: <category>/<test>.<build>: <stage> failed. [...]
- xx:
- xx: <category>/<test>.<build>: ****** <stage> failed *******
- xx: =============================== OUTPUT END ===============================
- </pre>
+<pre>
+xx: Test <category>/<test>.<build>: <stage>
+xx: =============================== OUTPUT BEGIN ===============================
+xx: [...]
+xx: <category>/<test>.<build>: <stage> failed. [...]
+xx:
+xx: <category>/<test>.<build>: ****** <stage> failed *******
+xx: =============================== OUTPUT END ===============================
+</pre>
Hereby, <code><stage></code> indicates the stage in which the
test failed:
<ul>
<p>
A test usually consists of a source file and an output file for
comparison (under the testsuite directory <code>tests</code>):
- <pre>
-
- category/test.cc
- category/test.output
- </pre>
+<pre>
+category/test.cc
+category/test.output
+</pre>
<code>category</code> will be one of the existing subdirectory
under <code>tests/</code>, e.g., <code>lac/</code>, <code>base/</code>,
or <code>mpi/</code>. Historically, we have grouped tests into the
<a name="restrictbuild"></a>
- <h3>Restricting tests for build configurations</h3>
+ <h3>Restricting tests to build configurations</h3>
<p>
Comparison file can actually be named in a more complex way than
just <code>category/test.output</code>:
- <pre>
-
- category/test.[with_<feature>=<on|off>.]*[mpirun=<x>.][expect=<y>.][binary.][<debug|release>.]output
- </pre>
+<pre>
+category/test.[compiler=<regex>=<yes|no>.]*[with_<feature>=<on|off>.]*[mpirun=<x>.][expect=<y>.][binary.][<debug|release>.]output
+</pre>
Normally, a test will be set up so that it runs twice, once in debug and
once in release configuration.
If a specific test can only be run in debug or release configurations but
not in both it is possible to restrict the setup by prepeding
<code>.debug</code> or <code>.release</code> directly before
<code>.output</code>, e.g.:
- <pre>
-
- category/test.debug.output
- </pre>
+<pre>
+category/test.debug.output
+</pre>
This way, the test will only be set up to build and run against the debug
library. If a test should run in both configurations but, for some
reason, produces different output (e.g., because it triggers an
assertion in debug mode), then you can just provide two different output
files:
- <pre>
-
- category/test.debug.output
- category/test.release.output
- </pre>
+<pre>
+category/test.debug.output
+category/test.release.output
+</pre>
</p>
+ <a name="restrictcompiler"></a>
+ <h3>Restricting tests to specific compiler and compiler versions</h3>
+ <p>
+ In a similar vain as for build configurations, it is possible to restrict
+ tests to specific compiler versions, e.g.:
+<pre>
+category/test.compiler=GNU=yes.output, or
+category/test.compiler=ICC-14=no.output
+</pre>
+ These tests will only be set up if the specified regular expression
+ matches (in case of <code>=yes</code>), or doesn't match
+ (<code>=no</code>) the string
+ <code>${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}</code>.
+ Common compiler names are <code>GNU</code>, <code>Clang</code> or
+ <code>Intel</code>.
<a name="restrictfeature"></a>
- <h3>Restricting tests for feature configurations</h3>
+ <h3>Restricting tests to feature configurations</h3>
<p>
In a similar vain as for build configurations, it is possible to restrict
tests to specific feature configurations, e.g.:
- <pre>
-
- category/test.with_umfpack=on.output, or
- category/test.with_zlib=off.output
- </pre>
+<pre>
+category/test.with_umfpack=on.output, or
+category/test.with_zlib=off.output
+</pre>
These tests will only be set up if the specified feature was configured.
It is possible to provide different output files for disabled/enabled
features, e.g.
- <pre>
-
- category/test.with_64bit_indices=on.output
- category/test.with_64bit_indices=off.output
- </pre>
+<pre>
+category/test.with_64bit_indices=on.output
+category/test.with_64bit_indices=off.output
+</pre>
It is also possible to declare multiple constraints subsequently, e.g.
- <pre>
-
- category/test.with_umfpack=on.with_zlib=on.output
- </pre>
+<pre>
+category/test.with_umfpack=on.with_zlib=on.output
+</pre>
</p>
<p>
<b>Note:</b> The tests in some subdirectories of <code>tests/</code> are
If a test should be run with MPI in parallel, the number of MPI
processes <code>N</code> with which a program needs to be run for
comparison with a given output file is specified as follows:
- <pre>
-
- category/test.mpirun=N.output
- </pre>
+<pre>
+category/test.mpirun=N.output
+</pre>
It is quite typical for an MPI-enabled test to have multiple output
files for different numbers of MPI processes.
</p>
<p>
If a test produces binary output add <code>binary</code> to the
output file to indicate this:
- <pre>
-
- category/test.binary.output
- </pre>
+<pre>
+category/test.binary.output
+</pre>
The testsuite ensures that a diff tool suitable for comparing binary
output files is used instead of the default diff tool, which (as in
the case of <code>numdiff</code>) might be unable to compare binary
If (for some reason) the test should succeed ending at a specific
test stage different than <code>PASSED</code> you can specify it via
<code>expect=<stage></code>, e.g.:
- <pre>
-
- category/test.expect=run.output
- </pre>
+<pre>
+category/test.expect=run.output
+</pre>
</p>
For the testcase, we usually start from one of the existing tests, copy
and modify it to where it does what we'd like to test. Alternatively,
you can also start from a template like this:
- <pre>
-
+<pre>
// ---------------------------------------------------------------------
// $Id$
//
//
// ---------------------------------------------------------------------
-
// a short (a few lines) description of what the program does
#include "../tests.h"
// all include files you need here
-
int main ()
{
std::ofstream logfile("output");
return 0;
}
- </pre>
+</pre>
<p>This code opens an output file <code>output</code> in the current working
directory and then writes all output you generate to it, through the
<p>
In order to run your new test, copy it to an appropriate category and
create an empty comparison file for it:
- <pre>
-
- category/my_new_test.cc
- category/my_new_test.output
- </pre>
+<pre>
+category/my_new_test.cc
+category/my_new_test.output
+</pre>
Now, rerun
- <pre>
-
- $ make setup_tests
- </pre>
+<pre>
+$ make setup_tests
+</pre>
so that your new test is picked up. After that it is possible to
invoke it with
- <pre>
-
- $ ctest -V -R "category/my_new_test"
- </pre>
+<pre>
+$ ctest -V -R "category/my_new_test"
+</pre>
</p>
<p>
<p>
The next step is to copy and rename this output file to the source
directory and replace the original comparison file with it:
- <pre>
-
- category/my_new_test.output
- </pre>
+<pre>
+category/my_new_test.output
+</pre>
At this point running the test again should be successful:
- <pre>
-
- $ ctest -V -R "category/my_new_test"
- </pre>
+<pre>
+$ ctest -V -R "category/my_new_test"
+</pre>
</p>
interested in getting new tests. If you have subversion write access
already, you can add the new test and the expected output
file:
- <pre>
-
- svn add category/my_new_test.cc
- svn add category/my_new_test.output
- svn commit -m "New test"
- </pre>
+<pre>
+svn add category/my_new_test.cc
+svn add category/my_new_test.output
+svn commit -m "New test"
+</pre>
If you don't have subversion write access, talk to us in the
discussion group; writing testcases is a worthy and laudable task,
and we would like to encourage it by giving people the opportunity to
folder under <cmake>./tests</cmake> that is named accordingly and put
a <code>CMakeLists.txt</code> file into it containing
</p>
- <pre>
-
- CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
- INCLUDE(${DEAL_II_SOURCE_DIR}/cmake/setup_testsubproject.cmake)
- PROJECT(testsuite CXX)
- INCLUDE(${DEAL_II_TARGET_CONFIG})
- DEAL_II_PICKUP_TESTS()
- </pre>
+<pre>
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
+INCLUDE(${DEAL_II_SOURCE_DIR}/cmake/setup_testsubproject.cmake)
+PROJECT(testsuite CXX)
+INCLUDE(${DEAL_II_TARGET_CONFIG})
+DEAL_II_PICKUP_TESTS()
+</pre>
href="http://cdash.kyomu.43-1.org/index.php?project=deal.II">CDash</a>
instance just invoke ctest within a build directory (or designated
build directory) with the <code>-S</code> option pointing to the
- <code>run_testsuite.cmake</code> script: <pre>
-
- $ ctest [...] -V -S ../tests/run_testsuite.cmake
- </pre>
+<pre>
+$ ctest [...] -V -S ../tests/run_testsuite.cmake
+</pre>
The script will run configure, build and ctest and submit the results
to the CDash server. It does not matter whether the configure, build
or ctest stages were run before that. Also in script mode, you can
<p>
<b>Note:</b> The following variables can be set to via
- <pre>
-
- ctest -D<variable>=<value> [...]
- </pre>
+<pre>
+ctest -D<variable>=<value> [...]
+</pre>
to control the behaviour of the <code>run_testsuite.cmake</code>
script:
- <pre>
-
- CTEST_SOURCE_DIRECTORY
- - The source directory of deal.II (usually ending in "[...]/deal.II"
- (equivalent to https://svn.dealii.org/trunk/deal.II)
- Note: This is _not_ the test directory ending in "[...]/tests"
- - If unspecified, "../deal.II" and "../../$ relative to the location
- of this script is used. If this is not a source directory, an error
- thrown.
-
- CTEST_BINARY_DIRECTORY
- - The designated build directory (already configured, empty, or non
- existent - see the information about TRACKs what will happen)
- - If unspecified the current directory is used. If the current
- directory is equal to CTEST_SOURCE_DIRECTORY or the "tests"
- directory, an error is thrown.
-
- CTEST_CMAKE_GENERATOR
- - The CMake Generator to use (e.g. "Unix Makefiles", or "Ninja", see
- $ man cmake)
- - If unspecified the current generator of a configured build directory
- will be used, otherwise "Unix Makefiles".
-
- TRACK
- - The track the test should be submitted to. Defaults to "Experimental".
- Possible values are:
-
- "Experimental" - all tests that are not specifically "build" or
- "regression" tests should go into this track
-
- "Build Tests" - Build tests that configure and build in a
- clean directory and run the build tests
- "build_tests/*"
-
- "Nightly" - Reserved for nightly regression tests for
- build bots on various architectures
-
- "Regression Tests" - Reserved for the regression tester
-
- CONFIG_FILE
- - A configuration file (see docs/development/Config.sample)
- that will be used during the configuration stage (invokes
- $ cmake -C ${CONFIG_FILE}). This only has an effect if
- CTEST_BINARY_DIRECTORY is empty.
-
- MAKEOPTS
- - Additional options that will be passed directly to make (or ninja).
- </pre>
+<pre>
+CTEST_SOURCE_DIRECTORY
+ - The source directory of deal.II (usually ending in "[...]/deal.II"
+ (equivalent to https://svn.dealii.org/trunk/deal.II)
+ Note: This is _not_ the test directory ending in "[...]/tests"
+ - If unspecified, "../deal.II" and "../../$ relative to the location
+ of this script is used. If this is not a source directory, an error
+ thrown.
+
+CTEST_BINARY_DIRECTORY
+ - The designated build directory (already configured, empty, or non
+ existent - see the information about TRACKs what will happen)
+ - If unspecified the current directory is used. If the current
+ directory is equal to CTEST_SOURCE_DIRECTORY or the "tests"
+ directory, an error is thrown.
+
+CTEST_CMAKE_GENERATOR
+ - The CMake Generator to use (e.g. "Unix Makefiles", or "Ninja", see
+ $ man cmake)
+ - If unspecified the current generator of a configured build directory
+ will be used, otherwise "Unix Makefiles".
+
+TRACK
+ - The track the test should be submitted to. Defaults to "Experimental".
+ Possible values are:
+
+ "Experimental" - all tests that are not specifically "build" or
+ "regression" tests should go into this track
+
+ "Build Tests" - Build tests that configure and build in a
+ clean directory and run the build tests
+ "build_tests/*"
+
+ "Nightly" - Reserved for nightly regression tests for
+ build bots on various architectures
+
+ "Regression Tests" - Reserved for the regression tester
+
+CONFIG_FILE
+ - A configuration file (see docs/development/Config.sample)
+ that will be used during the configuration stage (invokes
+ $ cmake -C ${CONFIG_FILE}). This only has an effect if
+ CTEST_BINARY_DIRECTORY is empty.
+
+MAKEOPTS
+ - Additional options that will be passed directly to make (or ninja).
+</pre>
Furthermore, the variables described <a href="#setupconfigure">above</a> can also be
set and will be handed automatically down to <code>cmake</code>.
</p>
href="http://www.dealii.org/testsuite.html">test suite page</a> to
participate. Assuming you checked out deal.II into the directory
<code>deal.II</code>, running it is as simple as:
- <pre>
-
- cd deal.II
- mkdir build
- cd build
- ctest -j4 -S ../cmake/scripts/run_buildtest.cmake
- </pre>
+<pre>
+cd deal.II
+mkdir build
+cd build
+ctest -j4 -S ../cmake/scripts/run_buildtest.cmake
+</pre>
</p>
<p>
version control. If you want to specify a build configuration for
cmake use a <a href="../users/Config.sample">configuration file</a>
to preseed the cache as explained <a href="#submit">above</a>:
- <pre>
-
- $ ctest -DCONFIG_FILE="[...]/Config.sample" [...]
- </pre>
+<pre>
+$ ctest -DCONFIG_FILE="[...]/Config.sample" [...]
+</pre>
</p>
<meta name="keywords" content="deal dealii finite elements fem triangulation">
<meta http-equiv="content-language" content="en">
</head>
- <body>
-
- <p>
- <br />
- This page provides documentation for deal.II developers. At present, we
- have the following resources available:
- </p>
-
- <h2>Documentation</h2>
-
- <ul>
- <li> <p> Documentation of the <a href="svn.html">SVN Archive</a> and
- information on <a href="http://www.dealii.org/websvn/log.php?repname=deal.II+Repository&path=%2F&isdir=1&" target="_top">recent changes to the library</a>.
-
- <li> <p>
- <a href="cmake-internals.html">Build system internals</a>:
- This page provides implementation and development details about
- the CMake build system.
-
- <li> <p><a href="writing-documentation.html" target="body">Writing
- documentation</a>: To document the library and our
- application programs, we use
- <a href="http://www.doxygen.org/" target="_top">doxygen</a>.
- This page documents the basics of the format in
- which the documentation needs to be written in order to
- enable automatic documentation generation.
- </p>
-
- <li> <p><a href="porting.html" target="body">Porting
- <acronym>deal.II</acronym> to a new system</a>:
-
- <acronym>deal.II</acronym> uses CMake as build system
- and is fairly ISO (1998) C++ Standard compliant.
- So, porting to a reasonably <a
- href="http://www.opengroup.org/austin/">POSIX</a> compliant
- system with a reasonably ISO C++ compliant compiler shouldn't be
- much work. Other (mostly proprietary) systems might require more
- work. See the <a href="../readme.html" target="body">ReadMe</a>
- file for more information on already supported systems. This
- resource gives some hints for porting to unknown platforms.
- </p>
-
- <li> <p><a href="../doxygen/deal.II/CodingConventions.html"
- target="body">Coding conventions</a>: We try to adhere to a
- set of coding conventions to ensure that the use of different
- parts of the library is as uniform as possible. Please read
- through them if you think about contributing code.
-
- <li> <p><a href="testsuite.html" target="body">Running the testsuite</a>:
- <acronym>deal.II</acronym> has a testsuite that we run to
- make sure that our tests don't break any existing
- functionality. This page explains its use.
- </p>
- </ul>
-
- <h2>Resources</h2>
-
- <ul>
- <li> <p><a
- href="http://www.dealii.org/cgi-bin/regression_quick.pl"
- target="body">Results of regression tests:</a> Every night,
- the regression tests are run on some of our machines. The log of the
- results can be seen here.
- </p>
-
- <li> <p><a href="http://www.dealii.org//cgi-bin/build.pl">
- Results of build tests:</a> We also build the library each night on
- a variety of computers, using different compilers. The results of
- these builds is listed as well.
- </p>
-
- <li> <p><a href="http://www.math.tamu.edu/~heister/bench">
- Results of benchmarks:</a> We run a certain number of tests
- and track the performance over time.
- </p>
- </ul>
-
- <hr />
- <address>
- <a href="../authors.html" target="body">The deal.II Authors</a>
- $Date$
- </address>
- <div class="right">
- <a href="http://validator.w3.org/check?uri=referer" target="_top">
- <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
- <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
- </div>
-
- </body>
+<body>
+
+<p>
+
+<h1>Information for Developers</h1>
+
+<br />
+This page provides documentation for deal.II developers. At present, we
+have the following resources available:
+</p>
+
+<h2>Documentation</h2>
+
+<ul>
+<li> <p> Documentation of the <a href="svn.html">SVN Archive</a> and
+ information on <a href="http://www.dealii.org/websvn/log.php?repname=deal.II+Repository&path=%2F&isdir=1&" target="_top">recent changes to the library</a>.
+
+<li> <p>
+ <a href="cmake-internals.html">Build system internals</a>:
+ This page provides implementation and development details about
+ the CMake build system.
+
+<li> <p><a href="writing-documentation.html" target="body">Writing
+ documentation</a>: To document the library and our
+ application programs, we use
+ <a href="http://www.doxygen.org/" target="_top">doxygen</a>.
+ This page documents the basics of the format in
+ which the documentation needs to be written in order to
+ enable automatic documentation generation.
+ </p>
+
+<li> <p><a href="porting.html" target="body">Porting
+ <acronym>deal.II</acronym> to a new system</a>:
+
+ <acronym>deal.II</acronym> uses CMake as build system
+ and is fairly ISO (1998) C++ Standard compliant.
+ So, porting to a reasonably <a
+ href="http://www.opengroup.org/austin/">POSIX</a> compliant
+ system with a reasonably ISO C++ compliant compiler shouldn't be
+ much work. Other (mostly proprietary) systems might require more
+ work. See the <a href="../readme.html" target="body">ReadMe</a>
+ file for more information on already supported systems. This
+ resource gives some hints for porting to unknown platforms.
+ </p>
+
+<li> <p><a href="../doxygen/deal.II/CodingConventions.html"
+ target="body">Coding conventions</a>: We try to adhere to a
+ set of coding conventions to ensure that the use of different
+ parts of the library is as uniform as possible. Please read
+ through them if you think about contributing code.
+
+<li> <p><a href="testsuite.html" target="body">Running the testsuite</a>:
+ <acronym>deal.II</acronym> has a testsuite that we run to
+ make sure that our tests don't break any existing
+ functionality. This page explains its use.
+ </p>
+</ul>
+
+<h2>Resources</h2>
+
+<ul>
+<li> <p><a
+ href="http://www.dealii.org/cgi-bin/regression_quick.pl"
+ target="body">Results of regression tests:</a> Every night,
+ the regression tests are run on some of our machines. The log of the
+ results can be seen here.
+ </p>
+
+<li> <p><a href="http://www.dealii.org//cgi-bin/build.pl">
+ Results of build tests:</a> We also build the library each night on
+ a variety of computers, using different compilers. The results of
+ these builds is listed as well.
+ </p>
+
+<li> <p><a href="http://www.math.tamu.edu/~heister/bench">
+ Results of benchmarks:</a> We run a certain number of tests
+ and track the performance over time.
+ </p>
+</ul>
+
+<hr />
+<address>
+ <a href="../authors.html" target="body">The deal.II Authors</a>
+ $Date$
+</address>
+<div class="right">
+ <a href="http://validator.w3.org/check?uri=referer" target="_top">
+ <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
+ <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
+</div>
+
+</body>
</html>
function/variable declaration, global function or namespace, may
be preceded by a comment of the following form:
</p>
- <pre>
- /**
- * This is an example documentation.
- *
- * @author Wolfgang Bangerth, 2000
- */
- class TestClass
- {
- public:
- /**
- * Constructor
- */
- TestClass ();
-
- /**
- * Example function
- */
- virtual void test () const = 0;
-
- /**
- * Member variable
- */
- const unsigned int abc;
- };
- </pre>
+<pre>
+/**
+ * This is an example documentation.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+class TestClass
+{
+ public:
+ /**
+ * Constructor
+ */
+ TestClass ();
+
+ /**
+ * Example function
+ */
+ virtual void test () const = 0;
+
+ /**
+ * Member variable
+ */
+ const unsigned int abc;
+};
+</pre>
<p>
<acronym>doxygen</acronym> will then generate a page for the class
<code>TestClass</code> and document each of the member functions
<li> <em>Itemized lists:</em>
By writing comments like the following,
- <pre>
- /**
- * <ul>
- * <li> foo
- * <li> bar
- * </ul>
- */
- </pre>
+<pre>
+/**
+ * <ul>
+ * <li> foo
+ * <li> bar
+ * </ul>
+ */
+</pre>
you can get itemized lists both in the online and printed
documentation:
<ul>
<p>
If you write comments like this,
</p>
- <pre>
- /**
- * @verbatim
- * void foobar ()
- * {
- * i = 0;
- * }
- * @endverbatim
- */
- </pre>
+<pre>
+/**
+ * @verbatim
+ * void foobar ()
+ * {
+ * i = 0;
+ * }
+ * @endverbatim
+ */
+</pre>
you will get the lines between the verbatim environment with
the same formatting and in typewriter font:
- <pre>
- void foobar ()
- {
- i = 0;
- }
- </pre>
+<pre>
+void foobar ()
+{
+ i = 0;
+}
+</pre>
This is useful if you want to include small sample code snippets
into your documentation. In particular, it is important that
the formatting is preserved, which is not the case for all
preprocessor symbol <tt>DOXYGEN</tt> when running
<acronym>doxygen</acronym>. Therefore, the following template can be
used to avoid documentation:</p>
- <pre>
- documented code here
+<pre>
+/* documented code here */
- #ifndef DOXYGEN
+#ifndef DOXYGEN
- code here is compiled, but ignored by doxygen
+/* code here is compiled, but ignored by doxygen */
- #endif // DOXYGEN
- </pre>
+#endif // DOXYGEN
+</pre>
</ul>
<h3>Code examples for the usage of single classes</h3>
documentation. It can be grouped into the following categories:
</p>
-
-<table align="center" width="70%">
- <tr>
- <th width="40%"><a href="users/index.html"target="_top">Information for users</a></th>
- <td></td>
- <th width="40%"><a href="developers/index.html" target="_top">Information for developers</a></th>
- </tr>
-
- <tr>
- <td>
+<div style="text-align: center;">
+ <div style="clear: both; text-align: center; max-width: 580px; margin: auto;">
+ <div class="infobox">
+ <a href="users/index.html"target="_top">Information for users</a>
<div style="border:1px solid #aaa; background-color: #f9f9f9;
- padding: 5px; font-size: 88%;">
- <ol>
- <li><a href="readme.html" target="body">README and
- 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/index.html" target="_top">Manual</a></li>
- <li><a href="http://www.math.tamu.edu/~bangerth/videos.html" target="_top">Video lectures</a></li>
- <li><a href="reports/index.html" target="body">Technical reports</a></li>
- <li><a href="publications/index.html" target="body">Publications</a></li>
- </ol>
+ padding: 5px; font-size: 88%; text-align: left;">
+ <ol>
+ <li><a href="readme.html" target="body">README and
+ 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/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>
+ <li><a href="publications/index.html" target="body">Publications</a></li>
+ </ol>
</div>
- </td>
-
- <td></td>
+ </div>
- <td>
+ <div class="infobox">
+ <a href="developers/index.html" target="_top">Information for developers</a>
<div style="border:1px solid #aaa; background-color: #f9f9f9;
- padding: 5px; font-size: 88%;">
- <ol>
- <li><a href="developers/svn.html" target="body">SVN Archive</a></li>
- <li><a href="developers/cmake-internals.html" target="body">CMake internals</a></li>
- <li><a href="developers/writing-documentation.html" target="body">Writing documentation</a></li>
- <li><a href="developers/porting.html" target="body">Porting</a></li>
- <li><a href="doxygen/deal.II/CodingConventions.html" target="body">Coding conventions</a></li>
- <li><a href="developers/testsuite.html" target="body">Testsuite</a></li>
- </ol>
+ padding: 5px; font-size: 88%; text-align: left;">
+ <ol>
+ <li><a href="developers/svn.html" target="body">SVN Archive</a></li>
+ <li><a href="developers/cmake-internals.html" target="body">CMake internals</a></li>
+ <li><a href="developers/writing-documentation.html" target="body">Writing documentation</a></li>
+ <li><a href="developers/porting.html" target="body">Porting</a></li>
+ <li><a href="doxygen/deal.II/CodingConventions.html" target="body">Coding conventions</a></li>
+ <li><a href="developers/testsuite.html" target="body">Testsuite</a></li>
+ </ol>
</div>
- </td>
- </tr>
-</table>
-
-<br>
-<br>
+ </div>
+ </div>
+</div>
+<div style="clear: both;">
+ <br>
<hr />
<address>
<a href="authors.html" target="body">The deal.II Authors</a>
<a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
<img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
</div>
+</div>
</body>
</html>
)
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/header.html.in
- ${CMAKE_CURRENT_BINARY_DIR}/header.html
+ ${CMAKE_CURRENT_SOURCE_DIR}/deal.css
+ ${CMAKE_CURRENT_BINARY_DIR}/deal.II/deal.css
+ COPYONLY
)
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/footer.html
- ${CMAKE_CURRENT_BINARY_DIR}/footer.html
+ ${CMAKE_CURRENT_SOURCE_DIR}/stylesheet.css
+ ${CMAKE_CURRENT_BINARY_DIR}/stylesheet.css
COPYONLY
)
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/deal.css
- ${CMAKE_CURRENT_BINARY_DIR}/deal.II/deal.css
+ ${CMAKE_CURRENT_SOURCE_DIR}/images/logo200.png
+ ${CMAKE_CURRENT_BINARY_DIR}/logo200.png
COPYONLY
)
+CONFIGURE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_header.pl
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_header.pl
+ )
+
+CONFIGURE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mod_footer.pl
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_footer.pl
+ )
+
+
+#
+# Generate header, footer and style files for doxygen
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/header.html
+ ${CMAKE_CURRENT_BINARY_DIR}/footer.html
+ COMMAND ${DOXYGEN_EXECUTABLE} -w html header.html footer.html style.css options.dox
+ COMMAND ${PERL_EXECUTABLE} -pi~ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_header.pl header.html
+ COMMAND ${PERL_EXECUTABLE} -pi~ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_footer.pl footer.html
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/options.dox
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_header.pl
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/mod_footer.pl
+ )
+
#
# Finalize the doxygen configuration:
#
tutorial
images
${CMAKE_CURRENT_BINARY_DIR}/options.dox
+ ${CMAKE_CURRENT_BINARY_DIR}/header.html
+ ${CMAKE_CURRENT_BINARY_DIR}/footer.html
${_doxygen_input}
- COMMENT "Generating documentation via doxygen. This may take a _really_ long time..."
+ COMMENT "Generating documentation via doxygen."
VERBATIM
)
ADD_CUSTOM_TARGET(doxygen ALL
+++ /dev/null
- <hr size="1" />
- <address style="align: right;">
- <small>
- <img src="logo200.png" alt="deal.II" />
- documentation generated on $datetime by
- <a href="http://www.doxygen.org/index.html">doxygen</a>
- $doxygenversion
- </small>
- </address>
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
- <title>$title</title>
- <link href="$relpath$doxygen.css" rel="stylesheet" type="text/css">
- <link href="$relpath$tabs.css" rel="stylesheet" type="text/css">
- <link href="$relpath$deal.css" rel="stylesheet" type="text/css">
- <link href="search/search.css" rel="stylesheet" type="text/css"/>
-
- <script type="text/javascript" src="search/search.js"></script>
- <script type="text/javascript" src="$relpath$jquery.js"></script>
- <script type="text/javascript" src="$relpath$dynsections.js"></script>
-
- <link rel="SHORTCUT ICON" href="http://www.dealii.org/favicon.ico">
- <meta name="copyright" content="Copyright (C) 1998 - 2013 by the deal.II Authors">
- <meta name="deal.II-version" content="@DEAL_II_PACKAGE_VERSION@">
- </head>
-
- <body>
/**
* @mainpage
*
- * @image html logo200.png
- *
* 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
* so until we run out of tasks and the ones that were created have been
* worked on.
*
- * This is essentially what the WorkStream class does: You give it an iterator
+ * This is essentially what the WorkStream::run function does: You give it an iterator
* range from which it can draw objects to work on (in the above case it is
* the interval given by <code>dof_handler.begin_active()</code> to
* <code>dof_handler.end()</code>), and a function that would do the work on
* each item (the function <code>MyClass::assemble_on_one_cell</code>)
* together with an object if it is a member function.
*
- * Essentially, the way the <code>MyClass::assemble_system</code>
- * function could be written then is like this (note that this is not quite
+ * In the following, let us lay out a rationale for why the functions in the
+ * WorkStream namespace are implemented the way they are. More information on
+ * their implementation can be found in the @ref workstream_paper .
+ * To see the WorkStream class used in practice on tasks like the ones
+ * outlined above, take a look at the step-9, step-13, step-14, step-32, step-35 or step-37
+ * tutorial programs.
+ *
+ * To begin with, given the brief description above,
+ * the way the <code>MyClass::assemble_system</code>
+ * function could then be written is like this (note that this is not quite
* the correct syntax, as will be described below):
* @code
template <int dim>
* function with the cell and scratch and per task objects which will be filled
* in at the positions indicated by <code>std_cxx1x::_1, std_cxx1x::_2</code> and <code>std_cxx1x::_3</code>.
*
- * To see the WorkStream class used in practice on tasks like the ones
- * outlined above, take a look at the step-32, step-35 or step-37
- * tutorial programs.
+ * There are refinements to the WorkStream::run function shown above.
+ * For example, one may realize that the basic idea above can only scale
+ * if the copy-local-to-global function is much quicker than the
+ * local assembly function because the former has to run sequentially.
+ * This limitation can only be improved upon by scheduling more work
+ * in parallel. This leads to the notion of coloring the graph of
+ * cells (or, more generally, iterators) we work on by recording
+ * which write operations conflict with each other. Consequently, there
+ * is a third version of WorkStream::run that doesn't just take a
+ * range of iterators, but instead a vector of vectors consisting of
+ * elements that can be worked on at the same time. This concept
+ * is explained in great detail in the @ref workstream_paper , along
+ * with performance evaluations for common examples.
*
*
* @anchor MTTaskSynchronization
# This file contains project-specific configurations for the
# deal.II documentation.
-PROJECT_NAME = "The deal.II library"
+PROJECT_NAME = "The deal.II Library"
PROJECT_NUMBER = "Reference documentation for deal.II version @DEAL_II_PACKAGE_VERSION@"
+PROJECT_LOGO = "logo200.png"
OUTPUT_DIRECTORY = .
# The doxygen documentation says this about the following flag:
HTML_FILE_EXTENSION = .html
HTML_HEADER = header.html
HTML_FOOTER = footer.html
-
+USE_MATHJAX = YES
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 200
+HTML_EXTRA_STYLESHEET = stylesheet.css
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
GENERATE_MAN = NO
-GENERATE_XML = NO
+GENERATE_XML = YES
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = YES
-DOT_IMAGE_FORMAT = png
-MAX_DOT_GRAPH_DEPTH = 3
+DOT_IMAGE_FORMAT = svg
+MAX_DOT_GRAPH_DEPTH = 5
DOT_TRANSPARENT = NO
GENERATE_LEGEND = YES
--- /dev/null
+
+use Sys::Hostname;
+my $host = hostname;
+
+my $hosting = << 'EOT'
+ 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
+ ;
+
+if ($host eq "simweb")
+{
+ s/\$doxygenversion/\$doxygenversion $hosting/;
+}
--- /dev/null
+
+
+# Modify these to enter the current data automatically
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
+$year += 1900;
+
+if (m'</head>')
+{
+ print '<link href="$relpath$deal.css" rel="stylesheet" type="text/css"></link>', "\n";
+ print '<link rel="SHORTCUT ICON" href="http://www.dealii.org/deal.ico"></link>', "\n";
+ print '<meta name="author" content="The deal.II Authors <authors@dealii.org>"></meta>', "\n";
+ print '<meta name="copyright" content="Copyright (C) 1998 - ', $year, ' by the deal.II authors"></meta>', "\n";
+ print '<meta name="deal.II-version" content="@DEAL_II_PACKAGE_VERSION@"></meta>', "\n";
+}
+
+s/\$projectname// unless (m/<title>/);
-//
-// Copyright (C) 1998 - 2013 by the deal.II authors
-//
-h1, h2, h3, h4, h5, h6 {
- color: Black;
- background: none;
- font-weight: normal;
- margin: 0;
- padding-top: 0.5em;
- padding-bottom: 0.17em;
- border-bottom: 1px solid #aaaaaa;
-}
-
-h1 {
- font-size: 175%;
-}
-
-h2 {
- font-size: 144%;
- font-weight: bold;
-}
-
-h3 { font-size: 120%;
- padding-bottom: 0.17em;
- font-weight: bold;
- border-bottom: 1px dashed #aaaaaa; }
-h4 { font-size: 110%;
- border-bottom: none;
- font-weight: bold;
-}
-h5 { font-size: 100%;
- border-bottom: none;
- font-weight: bold;
-}
-h6 { font-size: 80%;
- border-bottom: none;
- font-weight: bold;
-}
-
-h1.head {
- position:relative;
- text-align:center;
- font-weight: bold;
- color:black;
- padding-top: 10px;
- padding-bottom: 10px;
- border-bottom: 0;
-}
-
-div.head {
- background-color: #CCD8E8;
- border: 1px solid #B0B0B0;
- width: 100%;
- margin: 2px;
- padding: 2px;
- text-align:center;
-}
-
-CAPTION { font-weight: bold }
-DIV.qindex {
- width: 100%;
- background-color: #eeeeff;
- border: 1px solid #B0B0B0;
- text-align: center;
- margin: 2px;
- padding: 2px;
-}
-A.qindex {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D;
- padding: 2px;
-}
-A.qindex:visited {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D
- padding: 2px;
-}
-A.qindex:hover {
- text-decoration: none;
- background-color: #ddddff;
- padding: 2px;
-}
-A.qindexHL {
- text-decoration: none;
- font-weight: bold;
- background-color: #6666cc;
- color: #ffffff;
- padding: 2 6px;
- border: 1px double #9295C2;
- }
-A.qindexHL:hover {
- text-decoration: none;
- background-color: #6666cc;
- color: #ffffff;
- padding: 2px 6px;
-}
-A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
-A.el { text-decoration: none; font-weight: normal; color: #1A41FF; }
-A.el:visited { text-decoration: none; font-weight: normal; color: #1A41B0; }
-A.elRef { font-weight: bold }
-A.code { text-decoration: none; font-weight: normal; color: #1A419D}
-A.codeRef { font-weight: normal; color: #1A419D}
-A:hover { text-decoration: none; background-color: #f2f2ff }
-DL.el { margin-left: -1cm }
-PRE.fragment {
- background-color: #f5f5f5;
- margin-top: 4px;
- margin-bottom: 4px;
- margin-left: 2px;
- margin-right: 8px;
-}
-DIV.fragment {
- border: 1px solid #CCCCCC;
- background-color: #f5f5f5;
- padding: 6px;
-}
-DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
-TD.md { background-color: #F4F4FB; font-weight: bold; }
-TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
-TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
-DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
-DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
-BODY {
- background: white;
- color: black;
- margin-right: 20px;
- margin-left: 20px;
- font-family: sans-serif;
-}
-TD.indexkey {
- background-color: #eeeeff;
- font-weight: bold;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
- border: 1px solid #CCCCCC;
-}
-TD.indexvalue {
- background-color: #eeeeff;
- font-style: italic;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
- border: 1px solid #CCCCCC;
-}
-TR.memlist {
- background-color: #f0f0f0;
-}
-P.formulaDsp { text-align: center; }
-IMG.formulaDsp { }
-IMG.formulaInl { vertical-align: middle; }
-SPAN.keyword { color: #008000 }
-SPAN.keywordtype { color: #604020 }
-SPAN.keywordflow { color: #e08000 }
-SPAN.comment { color: #800000 }
-SPAN.preprocessor { color: #806020 }
-SPAN.stringliteral { color: #002080 }
-SPAN.charliteral { color: #008080 }
-.mdTable {
- border: 1px solid #868686;
- background-color: #F4F4FB;
-}
-.mdRow {
- padding: 8px 10px;
-}
-.mdescLeft {
- font-size: smaller;
- font-family: Arial, Helvetica, sans-serif;
- background-color: #FAFAFA;
- padding-left: 8px;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
-}
-.mdescRight {
- font-size: smaller;
- font-family: Arial, Helvetica, sans-serif;
- font-style: italic;
- background-color: #FAFAFA;
- padding-left: 4px;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
- padding-bottom: 0px;
- padding-right: 8px;
-}
-.memItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-family: Geneva, Arial, Helvetica, sans-serif;
- font-size: 12px;
-}
-.memItemRight {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-family: Geneva, Arial, Helvetica, sans-serif;
- font-size: 13px;
-}
-.memTemplItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-family: Geneva, Arial, Helvetica, sans-serif;
- font-size: 12px;
-}
-.memTemplParams {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-family: Geneva, Arial, Helvetica, sans-serif;
- font-size: 12px;
-}
-.memTemplItemRight {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-family: Geneva, Arial, Helvetica, sans-serif;
- font-size: 13px;
-}
-.search { color: #003399;
- font-weight: bold;
-}
-FORM.search {
- margin-bottom: 0px;
- margin-top: 0px;
-}
-INPUT.search { font-size: 75%;
- color: #000080;
- font-weight: normal;
- background-color: #eeeeff;
-}
-TD.tiny { font-size: 75%;
-}
-
-dt.glossary {
- font-size: large;
- font-weight: bold;
-}
-table.tutorial {
- color: black;
- border: 1px solid #aaa;
- background-color: #f9f9f9;
- padding: 5px;
- font-size: 95%;
+#titlearea
+{
+ background-color: #0000ff;
+ color: #80ff00;
}
<p>
<b>However, <acronym>deal.II</acronym> is not in the public domain, it
is property of and copyrighted by the
- <a href="authors.html"><acronym>deal.II</acronym> authors</a>, and
+ <a href="authors.html"><acronym>deal.II</acronym> Authors</a>, and
there are restrictions on its use:</b>
The legally binding license is the <a href="#license-text">GNU Lesser
General Public License</a> (LGPL) as published by the Free Software
<a href="doxygen/tutorial/index.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">Video lectures</a><br />
+ target="_top">Wolfgang's lectures</a><br />
</p>
<hr>
</p>
<ol>
+ <li>
+ Changed: The kinds of template arguments for the VectorTools::interpolate
+ function taking a Mapping as first argument has changed. This was done to
+ work around a bug in the Intel ICC compiler which led to linker errors. Since
+ the actual function argument list remains unchanged, the only way you will
+ notice this change is if you <i>explicitly</i> specify template arguments.
+ The only place one would typically do that is if you take the address of
+ a template function. Since this is not a common operation, the impact of this
+ change is probably limited.
+ <br>
+ (Wolfgang Bangerth, 2013/11/27)
+ </li>
+
<li>
Changed: The ghost handling of the parallel::distributed::Vector class has
been reworked: The vector now carries a global state that stores whether
<ol>
+ <li> Fixed: Missing instantiations of SparseDirectMUMPS have been added.
+ <br>
+ (Timo Heister, 2013/11/25)
+ </li>
+
<li> New: introduced "make test" that runs a minimal set of tests. We
encourage every user to run this, especially if they run in to problems.
The tests are automatically picked depending on the configuration and
</li>
<li> Changed: step-9, step-13 and step-14 have been converted to use the
- more modern WorkStream concept for assembling linear systems in parallel.
+ more modern WorkStream concept for assembling linear systems and computing
+ error indicators in parallel.
<br>
(Bruno Turcksin, Wolfgang Bangerth, 2013/10/26)
</li>
<h3>Specific improvements</h3>
<ol>
+ <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
+ by the update flags that are passed to the constructor of all FEValues, FEFaceValues
+ and FESubfaceValues objects. If a user attempts an operation for which the
+ corresponding flag was not specified, an exception is generated. This exception
+ did say previously what the cause was, but it was not overly explicit.
+ The exception now generates a message that says exactly what is going wrong.
+ <br>
+ (Wolfgang Bangerth, 2013/12/01)
+ </li>
+
+ <li> Fixed: GridGenerator::truncated_cone() failed if half_length < 0.5*radius in 3d.
+ <br>
+ (Timo Heister, 2013/11/25)
+ </li>
+
+ <li> Fixed: make_hanging_node_constraints failed with an exception in a
+ parallel::distributed computation if the element is
+ RaviartThomas (and probably others).
+ <br>
+ (Timo Heister, 2013/11/23)
+ </li>
+
+ <li> Improved: CMake: Added a configuration check for incompatible ninja
+ + icc setup, fixed several setup and performance issues with the
+ testsuite.
+ <br>
+ (Matthias Maier, 2013/11/20)
+ </li>
+
<li> Changed: when a dealii::Exception is thrown, defer the symbol lookup of the
stack trace to when it is needed. This improves performance if what() is never
called.
</li>
<li> Fixed: GridGenerator::parallelogram was not instantiated properly
- on intel compilers.
+ when using intel compilers.
<br>
(Timo Heister, 2013/11/17)
</li>
(Wolfgang Bangerth, 2013/11/13)
</li>
+ <li> Cleanup: Removed obsolete files and files with unknown licensing
+ status from the source tree. Along the way, parameter_gui now uses
+ default icons from the desktop environment instead of bundled ones.
+ <br>
+ (Matthias Maier, 2013/11/11)
+ </li>
+
<li> New: There is now a framework for coloring graphs, with functions
in namespace GraphColoring.
<br>
journal = {ACM Trans. Math. Softw.},
year = 2011,
volume = 38,
- pages = {14/1--28}}
+ pages = {14/1--28}
+}
+
+@Article{KronbichlerKormann2012,
+ author = {M. Kronbichler and K. Kormann},
+ title = {A generic interface for parallel cell-based finite element operator application},
+ journal = {Comput. Fluids},
+ year = 2012,
+ volume = 63,
+ pages = {135--147},
+ doi = {10.1016/j.compfluid.2012.04.012}
+}
<body>
- <h2>Publications on and with <acronym>deal.II</acronym></h2>
+ <h1>Publications on and with <acronym>deal.II</acronym></h1>
<p>
Our institutes are evaluated at regular intervals. Consequently,
<a name="referencing"> </a>
- <h3>Referencing <acronym>deal.II</acronym></h3>
+ <h2>Referencing <acronym>deal.II</acronym></h2>
<p>
If you write a paper using results obtained with the help of
(<a
href="http://www.isc.tamu.edu/publications-reports/tr/0602.pdf">Preprint</a>)
<br>
- <pre>
- @Article{BangerthHartmannKanschat2007,
- author = {W. Bangerth and R. Hartmann and G. Kanschat},
- title = {{deal.II} -- a General Purpose Object Oriented Finite Element Library},
- journal = {ACM Trans. Math. Softw.},
- year = 2007,
- volume = 33,
- number = 4,
- pages = {24/1--24/27}
- }</pre>
+<pre>
+@Article{BangerthHartmannKanschat2007,
+ author = {W. Bangerth and R. Hartmann and G. Kanschat},
+ title = {{deal.II} -- a General Purpose Object Oriented Finite Element Library},
+ journal = {ACM Trans. Math. Softw.},
+ year = 2007,
+ volume = 33,
+ number = 4,
+ pages = {24/1--24/27}
+}
+</pre>
</li>
<li> <a href="http://www.math.tamu.edu/~bangerth"
target="_top">W. Bangerth</a>,
To be found on the project webpage <a href="http://www.dealii.org"
target="_top">http://www.dealii.org</a>
<br>
- <pre>
- @Manual{DealIIReference,
- title = {{\tt deal.{I}{I}} Differential Equations Analysis Library,
- Technical Reference},
- author = {W. Bangerth and T. Heister and G. Kanschat and others},
- note = {\texttt{http://www.dealii.org}},
- url = {http://www.dealii.org}
- }</pre>
+<pre>
+@Manual{DealIIReference,
+ title = {{\tt deal.{I}{I}} Differential Equations Analysis Library, Technical Reference},
+ author = {W. Bangerth and T. Heister and G. Kanschat and others},
+ note = {\texttt{http://www.dealii.org}},
+ url = {http://www.dealii.org}
+}
+</pre>
</li>
</ol>
<p>
The following publications explain in great detail the
- implementation of algorithms and data structures of the hp, multigrid and
- distributed mesh components of deal.II:
+ implementation of algorithms and data structures of the hp, multigrid,
+ distributed mesh, and matrix-free components of deal.II:
</p>
<ol>
Comput. & Struct., vol. 82, pp. 2437-2445, 2004
</li>
+ <li> M. Kronbichler, K. Kormann
+ <br>
+ <strong>A generic interface for parallel cell-based finite element
+ operator application
+ </strong>
+ <br>
+ Computers and Fluids, vol. 63, pp. 135-147, 2012
+ <br>
+ DOI: <a href="http://dx.doi.org/10.1016/j.compfluid.2012.04.012">10.1016/j.compfluid.2012.04.012</a>
+ </li>
+
<li> W. Bangerth, T. Heister
<br>
<strong>What makes computational open source software libraries successful?</strong>
</ul>
<a name="2013"> </a>
- <h3>Publications in 2013</h3>
+ <h2>Publications in 2013</h2>
<!-- Please enter alphabetically by name -->
<ol>
Msc thesis, University of Göttingen, Germany, 2013.
</li>
+ <li> O. Axelsson, P. Boyanova, M. Kronbichler, M. Neytcheva, X. Wu
+ <br>
+ <strong>Numerical and computational efficiency of solvers for
+ two-phase problems
+ </strong>
+ <br>
+ Comput. Math. Appl., 65, 301-314, 2013.
+ </li>
+
<li> A. Barker, T. Rees, M. Stoll
<br>
<strong>A fast solver for an H<sub>1</sub> regularized
</ol>
<a name="2012"> </a>
- <h3>Publications in 2012</h3>
+ <h2>Publications in 2012</h2>
<!-- Please enter alphabetically by name -->
<ol>
University of Uppsala, research report, 2012.
</li>
- <li> M. Kronbichler, K. Kormann
- <br>
- <strong>A generic interface for parallel cell-based finite element
- operator application
- </strong>
- <br>
- Computers and Fluids, vol. 63, pp. 135-147, 2012.
- </li>
-
<li> M. Kunkel
<br>
<strong>Nonsmooth Newton Methods and Convergence of
</ol>
<a name="2011"> </a>
- <h3>Publications in 2011</h3>
+ <h2>Publications in 2011</h2>
<!-- Please enter alphabetically by name -->
<ol>
<a name="2010"> </a>
- <h3>Publications in 2010</h3>
+ <h2>Publications in 2010</h2>
<!-- Please enter alphabetically by name -->
<ol>
</ol>
<a name="2009"> </a>
- <h3>Publications in 2009</h3>
+ <h2>Publications in 2009</h2>
<!-- Please enter alphabetically by name -->
<ol>
<a name="2008"> </a>
- <h3>Publications in 2008</h3>
+ <h2>Publications in 2008</h2>
<!-- Please enter alphabetically by name -->
<ol>
<a name="2007"> </a>
- <h3>Publications in 2007</h3>
+ <h2>Publications in 2007</h2>
<!-- Please enter alphabetically by name -->
<ol>
<li> N. Antonic, M. Vrdoljak
<a name="2006"> </a>
- <h3>Publications in 2006</h3>
+ <h2>Publications in 2006</h2>
<ol>
<a name="2005"> </a>
- <h3>Publications in 2005</h3>
+ <h2>Publications in 2005</h2>
<ol>
<a name="2004"> </a>
- <h3>Publications in 2004</h3>
+ <h2>Publications in 2004</h2>
<ol>
<li> <a href="http://www.math.tamu.edu/~bangerth"
<a name="2003"> </a>
- <h3>Publications in 2003</h3>
+ <h2>Publications in 2003</h2>
<ol>
<li>
<a name="2002"> </a>
- <h3>Publications in 2002</h3>
+ <h2>Publications in 2002</h2>
<ol>
<a name="2001"> </a>
- <h3>Publications in 2001</h3>
+ <h2>Publications in 2001</h2>
<ol>
<li> A. Barinka, T. Barsch, P. Charton, A. Cohen, S. Dahlke,
<a name="2000"> </a>
- <h3>Publications in 2000</h3>
+ <h2>Publications in 2000</h2>
<ol>
<a name="1999"> </a>
- <h3>Publications in 1999</h3>
+ <h2>Publications in 1999</h2>
<ol>
<li>
<a name="1998"> </a>
- <h3>Publications in 1998</h3>
+ <h2>Publications in 1998</h2>
<ol>
<li>
</p>
<ul>
<li>GNU/Linux: GCC version 4.1 or later; Clang version 3.0 or later;
- ICC versions 12* or 14* (version 13 is not supported)</li>
+ ICC versions 13* or 14*</li>
<li>Mac OS X: GCC version 4.1 or later; Clang version 3.0 or later.
Please see the <a href="https://code.google.com/p/dealii/wiki/MacOSX"
target="_top">deal.II Wiki</a> for installation instructions.</li>
</li>
</ul>
- <a name="installation"/>
+ <a name="installation"></a>
<h2>Installation</h2>
- <a name="unpacking"/>
+ <a name="unpacking"></a>
<h3>Unpacking</h3>
<p>
<p>
There are a number of papers that describe the overall design or
individual aspects of <acronym>deal.II</acronym>. Please refer to the
- papers listed at the top of the <a href="publications/index.html"
+ papers listed at the top of the <a href="../publications/index.html"
target="body">publications page</a> for full references. In addition,
there are the following reports:
<ul>
</li>
</ul>
- <hr />
- <address>
- <a href="authors.html" target="body">The deal.II Authors</a>
- </address>
- <div class="right">
- <a href="http://validator.w3.org/check?uri=referer" target="_top">
- <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
- <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
- </div>
+<hr />
+<address>
+ <a href="../authors.html" target="body">The deal.II Authors</a>
+ $Date$
+</address>
+<div class="right">
+ <a href="http://validator.w3.org/check?uri=referer" target="_top">
+ <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
+ <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
+</div>
+
</body>
</html>
//
body {
- background-image: none;
- background-color: #ECF0F4;
- color: Black;
- margin: 10px;
- padding: 0;
- font-family: sans-serif;
- counter-reset: section;
+ background-image: none;
+ background-color: #ECF0F4;
+ color: Black;
+ margin: 10px;
+ padding: 0;
+ font-family: sans-serif;
+ counter-reset: section;
}
body.title {
- background-color: #CCD8E8;
- margin: 0;
- padding: 2px;
+ background-color: #CCD8E8;
+ margin: 0;
+ padding: 2px;
}
body.gallery {
- background-color: #CCD8E8;
- margin: 0;
- padding: 2px;
+ background-color: #CCD8E8;
+ margin: 0;
+ padding: 2px;
}
body.navbar {
- background-color: #CCD8E8;
- margin: 2px;
- padding: 2px;
- font-family: sans-serif;
- font-size: 12px;
+ background-color: #CCD8E8;
+ margin: 2px;
+ padding: 2px;
+ font-family: sans-serif;
+ font-size: 12px;
}
div.toc {
}
frameset {
- background-color: white;
- border-color: black;
- border: 2px;
+ background-color: white;
+ border-color: black;
+ border: 2px;
}
a:hover { text-decoration: underline; }
}
h1.head {
- position:relative;
+ position:relative;
text-align:center;
- font-weight: bold;
- color:black;
- padding-top: 0;
- padding-bottom: 0;
- border-bottom: 0;
+ font-weight: bold;
+ color:black;
+ padding-top: 0;
+ padding-bottom: 0;
+ border-bottom: 0;
}
h1, h2, h3, h4, h5, h6 {
}
.figure { font-weight: bold;
- font-size: larger;
- }
+ font-size: larger;
+ }
.pagetoc {}
.chapter_title {}
span.parhead {
- font-weight: bold;
-}
+ font-weight: bold;
+}
span.example {
- font-weight: bold;
- font-style: italic;
+ font-weight: bold;
+ font-style: italic;
}
pre {
- padding: 0em;
- text-align: left;
- text-indent: 0;
- border: 1px dashed #2f6fab;
- color: Black;
- background-color: #f9f9f9;
- line-height: 1.1em;
-}
-
+ padding: 1em;
+ text-align: left;
+ text-indent: 0;
+ border: 1px dashed #2f6fab;
+ color: Black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
pre.cmake {
- padding: 1em;
- text-align: left;
- text-indent: 0;
- border: 1px solid #d06fab;
- color: Black;
- background-color: #f9f9f9;
- line-height: 1.1em;
-}
-
+ padding: 1em;
+ text-align: left;
+ text-indent: 0;
+ border: 1px solid #d06fab;
+ color: Black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
pre.sample {
- padding: 1em;
- text-align: left;
- text-indent: 0;
- border: 1px dashed #2f6fab;
- color: Black;
- background-color: #f9f9f9;
- line-height: 1.1em;
-}
-
+ padding: 1em;
+ text-align: left;
+ text-indent: 0;
+ border: 1px dashed #2f6fab;
+ color: Black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
table.navbar { }
table.tutorial {
color: black;
}
td.build {
- text-align: center;
- vertical-align: middle;
- font-size: small;
+ text-align: center;
+ vertical-align: middle;
+ font-size: small;
}
}
.weak {
- color: #808080;
- text-decoration: line-through;
+ color: #808080;
+ text-decoration: line-through;
}
.todo:before {
}
.deprecated {
- text-decoration: line-through;
+ text-decoration: line-through;
}
.attention {
- color: #f00080;
- font-weight: bold;
+ color: #f00080;
+ font-weight: bold;
}
.shout {
- color: #e000ff;
- text-decoration: blink;
- font-weight: bold;
+ color: #e000ff;
+ text-decoration: blink;
+ font-weight: bold;
+}
+
+div.border {
+ clear: both;
+ margin: auto;
+}
+
+div.infobox {
+ float: left;
+ width: 250px;
+ text-align: center;
+ margin-top: 1em;
+ margin-left: 20px;
+ margin-right: 20px;
}
necessary; <i>values for variables that are already in the cache
are not re-evaluated</i>. This means that calling <code>cmake</code>
a second time without any arguments at all in a situation like this
- <pre>
-
- mkdir build
- cd build
- cmake -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
- cmake ../deal.II
- </pre>
+<pre class="cmake">
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
+cmake ../deal.II
+</pre>
has no effect: In particular, the <code>CMAKE_INSTALL_PREFIX</code>
specified on the first invocation of <code>cmake</code> is
cached and therefore still valid after the second invocation
configuration parameters and thereby interact with the configuration
system in rather powerful (and, possibly, destructive) ways. For
example, the following commands
- <pre>
-
- mkdir build
- cd build
- cmake ../deal.II
- ccmake
- </pre>
+<pre class="cmake">
+mkdir build
+cd build
+cmake ../deal.II
+ccmake
+</pre>
first configure a bare-bone setup and then call
the <code>ccmake</code> program -- an interactive editor for the
cached variables. Similarly,
- <pre>
-
- mkdir build
- cd build
- cmake ../deal.II
- cmake -D<OPTION>=<VALUE> [...] ../deal.II
- </pre>
+<pre class="cmake">
+mkdir build
+cd build
+cmake ../deal.II
+cmake -D<OPTION>=<VALUE> [...] ../deal.II
+</pre>
sets a variable the second time around without destroying all
the configuration that has happened the first time around. Likewise,
- <pre>
-
- mkdir build
- cd build
- cmake ../deal.II
- cmake -DDEAL_II_WITH_METIS=OFF .
- cmake -DDEAL_II_WITH_TRILINOS=ON -DTRILINOS_DIR=/path/to/trilinos .
- </pre>
+<pre class="cmake">
+mkdir build
+cd build
+cmake ../deal.II
+cmake -DDEAL_II_WITH_METIS=OFF .
+cmake -DDEAL_II_WITH_TRILINOS=ON -DTRILINOS_DIR=/path/to/trilinos .
+</pre>
switches off support for the METIS library that may have been
automatically detected during the first invocation of
<code>cmake</code> and enables support for Trilinos by enabling
<p>
A cached variable can be set on the command line via
- <pre>
-
- cmake -D<VARIABLE>=<VALUE> .
- </pre>
+<pre class="cmake">
+cmake -D<VARIABLE>=<VALUE> .
+</pre>
Cached variables can be removed from the cache via
- <pre>
-
- cmake -U<VARIABLE> .
- </pre>
+<pre class="cmake">
+cmake -U<VARIABLE> .
+</pre>
It is possible to use <code>-U</code> together with a globbing
expression. E.g. to remove the current feature configuration and
rerun the autodetection one can invoke
- <pre>
-
- cmake -U"DEAL_II_WITH_*" .
- </pre>
+<pre class="cmake">
+cmake -U"DEAL_II_WITH_*" .
+</pre>
</p>
<a name="operatingccmake"></a>
A very convenient way to alter the configuration is to use the graphical
user interface <code>ccmake</code> to the
variables <code>cmake</code> stores upon running. It can be invoked via
- <pre>
-
- ccmake .
- </pre>
+<pre class="cmake">
+ccmake .
+</pre>
or by
- <pre>
-
- make edit_cache
- </pre>
+<pre class="cmake">
+make edit_cache
+</pre>
A reconfiguration (without editing the cache) can be run via
- <pre>
-
- make rebuild_cache
- </pre>
+<pre class="cmake">
+make rebuild_cache
+</pre>
</p>
<a name="operatingshortcuts"></a>
<p>
All variables starting with <code>WITH_</code> will be automatically
renamed to <code>DEAL_II_WITH_*</code>. So, it suffices to specify
- <pre>
-
- cmake -DWITH_MPI=ON <...>
- </pre>
+<pre class="cmake">
+cmake -DWITH_MPI=ON <...>
+</pre>
instead of the longer
- <pre>
-
- cmake -DDEAL_II_WITH_MPI=ON <...>
- </pre>
+<pre class="cmake">
+cmake -DDEAL_II_WITH_MPI=ON <...>
+</pre>
The same holds for all variables starting with <code>COMPONENT_</code>
and all individual component names: <code>COMPAT_FILES</code>,
<code>DOCUMENTATION</code>, <code>EXAMPLES</code>,
<p> The current list of primary build targets can be queried via
<code>make info</code>:
- <pre>
-
- ###
- #
- # 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
- #
- # edit_cache - runs 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
- #
- # 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
- #
- # test - runs 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
- #
- ###
- </pre>
+<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
+#
+# edit_cache - runs 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
+#
+# 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
+#
+# test - runs 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
+#
+###
+</pre>
<a name="buildinformation"></a>
A configuration run of <code>cmake</code> (or <code>ccmake</code>)
writes a short summary of the current configuration into
<code>CMAKE_BUILD_DIR/summary.log</code>:
- <pre>
-
- ###
- #
- # deal.II configuration:
- # CMAKE_BUILD_TYPE: DebugRelease
- # BUILD_SHARED_LIBS: ON
- # CMAKE_INSTALL_PREFIX: /tmp/deal.II/install
- # CMAKE_SOURCE_DIR: /tmp/deal.II/deal.II (Version 8.1.pre)
- # CMAKE_BINARY_DIR: /tmp/deal.II/build
- # CMAKE_CXX_COMPILER: GNU 4.7.3 on platform Linux x86_64
- # /usr/bin/c++
- #
- # Configured Features (DEAL_II_ALLOW_BUNDLED = ON, DEAL_II_ALLOW_AUTODETECTION = ON):
- # ( DEAL_II_WITH_64BIT_INDICES = OFF )
- # DEAL_II_WITH_ARPACK set up with external dependencies
- # DEAL_II_WITH_BOOST set up with external dependencies
- # [...]
- #
- # Component configuration:
- # DEAL_II_COMPONENT_COMPAT_FILES
- # ( DEAL_II_COMPONENT_DOCUMENTATION = OFF )
- # DEAL_II_COMPONENT_EXAMPLES
- # DEAL_II_COMPONENT_MESH_CONVERTER
- # ( DEAL_II_COMPONENT_PARAMETER_GUI = OFF )
- #
- # 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
- #
- ###
- </pre>
+<pre class="cmake">
+###
+#
+# deal.II configuration:
+# CMAKE_BUILD_TYPE: DebugRelease
+# BUILD_SHARED_LIBS: ON
+# CMAKE_INSTALL_PREFIX: /tmp/deal.II/install
+# CMAKE_SOURCE_DIR: /tmp/deal.II/deal.II (Version 8.1.pre)
+# CMAKE_BINARY_DIR: /tmp/deal.II/build
+# CMAKE_CXX_COMPILER: GNU 4.7.3 on platform Linux x86_64
+# /usr/bin/c++
+#
+# Configured Features (DEAL_II_ALLOW_BUNDLED = ON, DEAL_II_ALLOW_AUTODETECTION = ON):
+# ( DEAL_II_WITH_64BIT_INDICES = OFF )
+# DEAL_II_WITH_ARPACK set up with external dependencies
+# DEAL_II_WITH_BOOST set up with external dependencies
+# [...]
+#
+# Component configuration:
+# DEAL_II_COMPONENT_COMPAT_FILES
+# ( DEAL_II_COMPONENT_DOCUMENTATION = OFF )
+# DEAL_II_COMPONENT_EXAMPLES
+# DEAL_II_COMPONENT_MESH_CONVERTER
+# ( DEAL_II_COMPONENT_PARAMETER_GUI = OFF )
+#
+# 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
+#
+###
+</pre>
This summary is also printed at the end of the configuration phase.
It tells you about build and install directory locations, feature
configuration (whether a feature is enabled with external/internal
A more detailed version can be found in
<code>CMAKE_BUILD_DIR/detailed.log</code> that also includes detailed
information about feature configuration, e.g.
- <pre>
-
- # DEAL_II_WITH_BOOST set up with external dependencies
- # BOOST_VERSION = 1.52.0
- # BOOST_DIR =
- # Boost_INCLUDE_DIRS = /usr/include
- # Boost_LIBRARIES = /usr/lib64/libboost_serialization-mt.so;/usr/lib64/libboost_system-mt.so;
- # [...]
- </pre>
+<pre class="cmake">
+# DEAL_II_WITH_BOOST set up with external dependencies
+# BOOST_VERSION = 1.52.0
+# BOOST_DIR =
+# Boost_INCLUDE_DIRS = /usr/include
+# Boost_LIBRARIES = /usr/lib64/libboost_serialization-mt.so;/usr/lib64/libboost_system-mt.so;
+# [...]
+</pre>
If this information is not sufficient, you might want to have a look
at the following files in <code>CMAKE_BUILD_DIR</code>
<ul>
<code>cmake</code> (or <code>ccmake</code>) from the designated build
directory, so for example (a build directory under the source
directory):
- <pre>
-
- $ mkdir build
- $ cd build
- $ cmake ..
- </pre>
+<pre class="cmake">
+$ mkdir build
+$ cd build
+$ cmake ..
+</pre>
The big advantage is that source files and intermediate files are
strictly separated (highly desired for version control) and that you
can have multiple build directories (with different configuration) at
<p>
<b>Note:</b> However, under rare occasions an in-source build might be
useful or needed , so it is supported
- <pre>
-
- $ cmake .
- </pre>
+<pre class="cmake">
+$ cmake .
+</pre>
But we highly discourage it!
</p>
Cmake is a <i>Makefile Generator</i>. This allows to switch the
generator that is used to something different. If you for example want
to automatically generate an Eclipse project of deal.II, you can run
- <pre>
-
- $ cmake -G"Eclipse CDT4 - Unix Makefiles" [...]
- </pre>
+<pre class="cmake">
+$ cmake -G"Eclipse CDT4 - Unix Makefiles" [...]
+</pre>
and load up the build directory as a project directly into Eclipse.
Have a look at the <a href="https://code.google.com/p/dealii/w/list"
target="_top">Wiki</a> for more information.
<p>
An interesting alternative to (GNU) Make might also be <a
href="http://martine.github.io/ninja/">Ninja</a>. Configure via
- <pre>
-
- $ cmake -GNinja [...]
- </pre>
+<pre class="cmake">
+$ cmake -GNinja [...]
+</pre>
and run <code>ninja</code> instead of <code>make</code>.
</p>
If you want to only generate, compile and install a specific
component (most notably the documentation) you can use one of the
following top level targets:
- <pre>
-
- 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
- </pre>
+ <pre class="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
+</pre>
<a name="configure"></a>
<p>
Specifically, the following variables exist (the list may grow
over time, but names are standardized):
- <pre>
-
- DEAL_II_WITH_ARPACK
- DEAL_II_WITH_BOOST
- DEAL_II_WITH_FUNCTIONPARSER
- DEAL_II_WITH_LAPACK
- DEAL_II_WITH_METIS
- DEAL_II_WITH_MUMPS
- DEAL_II_WITH_MPI
- DEAL_II_WITH_NETCDF
- DEAL_II_WITH_P4EST
- DEAL_II_WITH_PETSC
- DEAL_II_WITH_SLEPC
- DEAL_II_WITH_THREADS
- DEAL_II_WITH_TRILINOS
- DEAL_II_WITH_UMFPACK
- DEAL_II_WITH_ZLIB
- DEAL_II_WITH_64BIT_INDICES
- </pre>
+<pre class="cmake">
+DEAL_II_WITH_ARPACK
+DEAL_II_WITH_BOOST
+DEAL_II_WITH_FUNCTIONPARSER
+DEAL_II_WITH_LAPACK
+DEAL_II_WITH_METIS
+DEAL_II_WITH_MUMPS
+DEAL_II_WITH_MPI
+DEAL_II_WITH_NETCDF
+DEAL_II_WITH_P4EST
+DEAL_II_WITH_PETSC
+DEAL_II_WITH_SLEPC
+DEAL_II_WITH_THREADS
+DEAL_II_WITH_TRILINOS
+DEAL_II_WITH_UMFPACK
+DEAL_II_WITH_ZLIB
+DEAL_II_WITH_64BIT_INDICES
+</pre>
They all have standard meaning with the exception of
two:
<ul>
<p>
Paths specified via <code>CMAKE_PREFIX_PATH</code> take
precedence, e.g. with
- <pre>
-
- cmake -DCMAKE_PREFIX_PATH=~/workspace/local ../deal.II
- </pre>
+<pre class="cmake">
+make -DCMAKE_PREFIX_PATH=~/workspace/local ../deal.II
+</pre>
libraries from <code>~/workspace/local</code> will be
preferred for dependency resolution.
</p>
<p>
Hints given by <code><library>_DIR</code> via command
line or environment for <i>some</i> libraries:
- <pre>
-
- cmake -DP4EST_DIR=~/workspace/p4est-install/ ../deal.II
- </pre>
+<pre class="cmake">
+make -DP4EST_DIR=~/workspace/p4est-install/ ../deal.II
+</pre>
or
- <pre>
-
- export P4EST_DIR=~/workspace/p4est-install/
- cmake ../deal.II
- </pre>
+<pre class="cmake">
+export P4EST_DIR=~/workspace/p4est-install/
+cmake ../deal.II
+</pre>
where <code>-D<library>_DIR</code> takes precedence
over environment.
</p>
<p>
Currently, the following variables will be considered:
- <pre>
-
- ARPACK_DIR,
- BOOST_DIR,
- HDF5_DIR,
- LAPACK_DIR (and BLAS_DIR),
- METIS_DIR,
- MUMPS_DIR (and SCALAPACK_DIR, BLACS_DIR),
- P4EST_DIR (and SC_DIR),
- PETSC_DIR and PETSC_ARCH (forming ${PETSC_DIR}/${PETSC_ARCH}),
- SLEPC_DIR (forming ${SLEPC_DIR}/${PETSC_ARCH}),
- TBB_DIR,
- TRILINOS_DIR,
- UMFPACK_DIR and SUITESPARSE_DIR (AMD_DIR, CHOLMOD_DIR, COLAMD_DIR, SUITESPARSECONFIG_DIR)
- </pre>
+<pre class="cmake">
+ARPACK_DIR,
+BOOST_DIR,
+HDF5_DIR,
+LAPACK_DIR (and BLAS_DIR),
+METIS_DIR,
+MUMPS_DIR (and SCALAPACK_DIR, BLACS_DIR),
+P4EST_DIR (and SC_DIR),
+PETSC_DIR and PETSC_ARCH (forming ${PETSC_DIR}/${PETSC_ARCH}),
+SLEPC_DIR (forming ${SLEPC_DIR}/${PETSC_ARCH}),
+TBB_DIR,
+TRILINOS_DIR,
+UMFPACK_DIR and SUITESPARSE_DIR (AMD_DIR, CHOLMOD_DIR, COLAMD_DIR, SUITESPARSECONFIG_DIR)
+</pre>
</p>
<li>
<code>Find<Module></code> mechanism may be set,
hinted or overwritten directly (variable names are highly
dependent on the actual library). You can get a list via
- <pre>
-
- make edit_cache
- </pre>
+<pre class="cmake">
+make edit_cache
+</pre>
and entering advanced configuration mode by pressing [t].
Variables that could not be determined are suffixed with
<code>-NOTFOUND</code> and may be set by hand.
need different revisions sometimes, in your own library directory,
you may receive an error message of the form:</p>
-<pre>
-
- CMake Warning at source/CMakeLists.txt:65 (ADD_LIBRARY):
- Cannot generate a safe runtime search path for target deal_II.g because
- files in some directories may conflict with libraries in implicit
- directories:
-
- runtime library [libtbb.so.2] in /usr/lib may be hidden by files in:
- /my/private/lib
+<pre class="cmake">
+CMake Warning at source/CMakeLists.txt:65 (ADD_LIBRARY):
+ Cannot generate a safe runtime search path for target deal_II.g because
+ files in some directories may conflict with libraries in implicit
+ directories:
- Some of these libraries may not be found correctly.
+ runtime library [libtbb.so.2] in /usr/lib may be hidden by files in:
+ /my/private/lib
+ Some of these libraries may not be found correctly.
</pre>
<p>This is not a problem of CMake or deal.II, but rather a general
<code>FIND_PACKAGE(...)</code> mechanism.
In this case you can set by hand:
- <pre>
-
- cmake -D<feature>_FOUND=true \
- -D<feature>_LIBRARIES="library;and;complete;link;interface" \
- ( -D<feature>_INCLUDE_DIRS="semicolon;separated;list;of;include;dirs" \
- -D<feature>_LINKER_FLAGS="..." \
- -D<feature>_<...depending on library...> )
- </pre>
+<pre class="cmake">
+cmake -D<feature>_FOUND=true \
+ -D<feature>_LIBRARIES="library;and;complete;link;interface" \
+ ( -D<feature>_INCLUDE_DIRS="semicolon;separated;list;of;include;dirs" \
+ -D<feature>_LINKER_FLAGS="..." \
+ -D<feature>_<...depending on library...> )
+</pre>
The first define ensures that <code>cmake</code> does not
call the corresponding <code>Find<lib>.cmake</code> module.
configuration:
(Here, these libraries have been compiled with the gfortran compiler
and need its support library):
- <pre>
-
- cmake -DLAPACK_FOUND=true \
- -DLAPACK_LIBRARIES="/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libflapack.a;/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libfblas.a" \
- -DLAPACK_LINKER_FLAGS="-lgfortran -lm"
- </pre>
+<pre class="cmake">
+cmake -DLAPACK_FOUND=true \
+ -DLAPACK_LIBRARIES="/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libflapack.a;/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libfblas.a" \
+ -DLAPACK_LINKER_FLAGS="-lgfortran -lm"
+</pre>
You can set these values on the command line, with <code>ccmake</code>
or by providing an initial cache file, see
</p>
Compilers can be switched either by command line or by setting
<code>CMAKE_(C|CXX|Fortran)_COMPILER</code>:
- <pre>
+<pre class="cmake">
+CC=mpicc CXX=mpicxx FC=mpif90 cmake <...>
- CC=mpicc CXX=mpicxx cmake <...>
-
- cmake -DCMAKE_C_COMPILER="mpicc" -DCMAKE_CXX_COMPILER="mpicxx" -DCMAKE_Fortran_COMPILER="mpif90" <...>
- </pre>
+cmake -DCMAKE_C_COMPILER="mpicc" -DCMAKE_CXX_COMPILER="mpicxx" -DCMAKE_Fortran_COMPILER="mpif90" <...>
+</pre>
Please note that
<ul>
<li>
<li>
Override the default configuration by setting the following
cached variables:
- <pre>
-
- CMAKE_CXX_FLAGS - used during all builds
- DEAL_II_CXX_FLAGS_DEBUG - additional flags for the debug library
- DEAL_II_CXX_FLAGS_RELEASE - additional flags for the release library
- </pre>
+<pre class="cmake">
+CMAKE_CXX_FLAGS - used during all builds
+DEAL_II_CXX_FLAGS_DEBUG - additional flags for the debug library
+DEAL_II_CXX_FLAGS_RELEASE - additional flags for the release library
+</pre>
The content of the cached variables will be preserved
and added <i>to the end</i> of the default compiler flags,
hence providing the possibility for overriding a flag. E.g.:
<code>-Wsign-compare</code>, set by the build system, can be
overwritten by specifying:
- <pre>
-
- cmake -DCMAKE_CXX_FLAGS="-Wno-sign-compare" <...>
- </pre>
+<pre class="cmake">
+cmake -DCMAKE_CXX_FLAGS="-Wno-sign-compare" <...>
+</pre>
<li>
Set the corresponding environment variables: <code>CFLAGS</code>,
the location, where the <acronym>deal.II</acronym> library will be
installed when invoking <code>make install</code> to is set with the
help of
- <pre>
-
- CMAKE_INSTALL_PREFIX
- </pre>
+<pre class="cmake">
+CMAKE_INSTALL_PREFIX
+</pre>
Please note that depending on whether
<code>DEAL_II_COMPONENT_COMPAT_FILES</code> is set, there will be
<ul>
<li>
With <code>DEAL_II_COMPONENT_COMPAT_FILES=ON</code>:
- <pre>
-
- ${CMAKE_INSTALL_PREFIX}/
- bin
- cmake/macros
- common
- common/scripts
- doc
- examples
- include
- lib
- lib/cmake/deal.II
- </pre>
+<pre class="cmake">
+${CMAKE_INSTALL_PREFIX}/
+ bin
+ cmake/macros
+ common
+ common/scripts
+ doc
+ examples
+ include
+ lib
+ lib/cmake/deal.II
+</pre>
<li>
With <code>DEAL_II_COMPONENT_COMPAT_FILES=OFF</code>:
- <pre>
-
- ${CMAKE_INSTALL_PREFIX}/
- bin
- include
- lib${LIB_SUFFIX}
- lib${LIB_SUFFIX}/cmake/deal.II
- share/deal.II/
- share/deal.II/cmake/macros
- share/deal.II/examples
- share/doc/deal.II/html
- </pre>
+<pre class="cmake">
+${CMAKE_INSTALL_PREFIX}/
+ bin
+ include
+ lib${LIB_SUFFIX}
+ lib${LIB_SUFFIX}/cmake/deal.II
+ share/deal.II/
+ share/deal.II/cmake/macros
+ share/deal.II/examples
+ share/doc/deal.II/html
+</pre>
</ul>
</p>
<p>
The default directory structure can be changed by by setting the
following variables:
- <pre>
-
- DEAL_II_CMAKE_MACROS_RELDIR
- DEAL_II_COMMON_RELDIR
- DEAL_II_DOCHTML_RELDIR
- DEAL_II_DOCREADME_RELDIR
- DEAL_II_EXAMPLES_RELDIR
- DEAL_II_EXECUTABLE_RELDIR
- DEAL_II_INCLUDE_RELDIR
- DEAL_II_LIBRARY_RELDIR
- DEAL_II_PROJECT_CONFIG_RELDIR
- </pre>
+<pre class="cmake">
+DEAL_II_CMAKE_MACROS_RELDIR
+DEAL_II_COMMON_RELDIR
+DEAL_II_DOCHTML_RELDIR
+DEAL_II_DOCREADME_RELDIR
+DEAL_II_EXAMPLES_RELDIR
+DEAL_II_EXECUTABLE_RELDIR
+DEAL_II_INCLUDE_RELDIR
+DEAL_II_LIBRARY_RELDIR
+DEAL_II_PROJECT_CONFIG_RELDIR
+</pre>
</p>
<h2>Initial cache file and advanced options</h2>
A sample configuration file for preloading the CMake cache with
- <pre>
-
- $ cmake -C Config.sample <...>
- </pre>
+<pre class="cmake">
+$ cmake -C Config.sample <...>
+</pre>
can be found <a href="Config.sample" target="_top">here</a>.
This sample configuration covers all options mentioned in this
documentation as well as some advanced aspects in feature
A common scenario is that you only want to build debug or optimized
libraries. This can be achieved using the following commands in
the build directory:
- <pre>
+<pre class="cmake">
+make deal_II.g # only debug library
+make deal_II # only release (optimized) library
+make all # both
- make deal_II.g # only debug library
- make deal_II # only release (optimized) library
- make all # both
-
- make obj_grid.release # all objects in ./source/grid in release configuration
- </pre>
+make obj_grid.release # all objects in ./source/grid in release configuration
+</pre>
</p>
<p>
For a complete list of possible targets that allow even
finer-grained control, do
- <pre>
-
- make help
- </pre>
+<pre class="cmake">
+make help
+</pre>
</p>
<p>
It is frequently useful to be able to see what a particular
command does. In that case, use the following:
- <pre>
-
- make deal_II.g VERBOSE=ON
- </pre>
+<pre class="cmake">
+make deal_II.g VERBOSE=ON
+</pre>
This will show, for every command executed, the exact command
line with which it was invoked, including compiler arguments,
etc. Every command <code>cmake</code> executes starts with
<body>
<h1>How to use CMake to configure your projects with <acronym>deal.II</acronym></h1>
+<p>
+ <code>cmake</code> is controlled by input files that by convention are
+ called <code>CMakeLists.txt</code>, listing both configuration commands
+ as well as dependencies between source files and targets.
+ This page presents some <code>CMakeLists.txt</code> examples for
+ potential use in your projects. (A detailed description of the
+ <acronym>deal.II</acronym> project configuration is given in the
+ <a href="cmake.html" target="body">deal.II CMake ReadMe</a>.)
+</p>
+
<div class="toc">
<ol>
<li><a href="#cmakesimple">Simple <code>CMakeLists.txt</code></a>
</ol>
</div>
-<p>
- <code>cmake</code> is the configuration and build tool we use
- in <acronym>deal.II</acronym>. Its advantage is not only that it makes
- configuration of <acronym>deal.II</acronym> itself simpler across
- platforms (compared to the older <code>autoconf/make</code> combination)
- but also that it <i>exports</i> information about the deal.II
- configuration that makes it particularly simple for projects
- using <acronym>deal.II</acronym> to configure and link against it.
-</p>
-
-<p>
- <code>cmake</code> is controlled by input files that by convention are
- called <code>CMakeLists.txt</code>, listing both configuration commands
- as well as dependencies between source files and targets.
- This page presents some <code>CMakeLists.txt</code> examples for
- potential use in your projects. (A detailed description of the
- <acronym>deal.II</acronym> project configuration is given in the
- <a href="cmake.html" target="body">deal.II CMake ReadMe</a>.)
-</p>
-
<a name="cmakesimple"></a>
<h2>Simple CMakeLists.txt</h2>
the <acronym>deal.II</acronym> directory tree.
The CMake build system sets up the following compatibility files (if
<code>DEAL_II_COMPONENT_COMPAT_FILES</code> is set, which is default):
- <pre>
-
- ${CMAKE_INSTALL_PREFIX}
- ./common/Make.global_options
- ./common/scripts/expand_instantiations
- ./common/scripts/make_dependencies
- ./common/scripts/report_features
- </pre>
+<pre>
+${CMAKE_INSTALL_PREFIX}/
+ 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
user Makefiles to:
- <pre>
-
- D=/path/install/dir
- </pre>
+<pre>
+D=/path/install/dir
+</pre>
where <code>/path/install/dir</code> is the directory set up via
<code>CMAKE_INSTALL_PREFIX</code> (the path
<acronym>deal.II</acronym> was installed to).
<li>Once your <code>deal.tag</code> file is in a location where
Doxygen can find it, add the following line to your Doxygen
configuration file:
- <pre>
-
+<pre>
TAGFILES = deal.tag=http://www.dealii.org/X.Y.Z/doxygen/deal.II
-
</pre>
where <code>X.Y.Z</code> refers to the release number for which
you downloaded the tag file.
<a href="../doxygen/tutorial/index.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">Video lectures</a><br />
+ target="_top">Wolfgang's lectures</a><br />
</p>
<hr>
<meta name="keywords" content="deal dealii finite elements fem triangulation">
<meta http-equiv="content-language" content="en">
</head>
- <body>
-
- <p>
- <br />
- This page gathers some information on developing programs based on
- <acronym>deal.II</acronym>, as well as on how to configure and use
- <acronym>deal.II</acronym>. At present, we have the following resources
- available:
- </p>
-
-
- <h2>Documentation</h2>
-
- <ul>
-
- <li> <p>
- <a href="cmake.html">deal.II CMake documentation</a>:
- This page provides extensive information about configuration and
- installation with the CMake build system.
-
- <li> <p><a href="cmakelists.html" target="body">Using CMake and
- <acronym>deal.II</acronym> in a user project</a>:
- This page covers how to use CMake in your own project.
- An overview of how to retrieve necessary information
- from a <acronym>deal.II</acronym> installation as well as how to
- write a <code>CMakeLists.txt</code> for a client project is given.
- </p>
-
- <li> <p><a href="doxygen.html">Linking your online documentation
- to the deal.II online manual</a>: After spending a lot of time
- writing good documentation for your code and putting it online,
- here we explain how to put links to the deal.II online manual into
- your documentation, so that readers can click through.
- </p>
-
- <li> <p><a href="https://code.google.com/p/dealii/issues/list" target="_top">Bugs</a>:
- Though well tested, <acronym>deal.II</acronym> certainly has
- bugs. If you want to report a bug (or enhancement request),
- go to the <a href="https://code.google.com/p/dealii/issues/list"
- target="_top">bug tracking system</a> and enter a new ticket
- for your issue.
- </p>
-
- </ul>
-
-
- <h2>Tutorials</h2>
-
- <p>
- The <a href="../doxygen/tutorial/index.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
- programs. You can also reach the tutorial link from the
- menu bar at the left. There is also an extensive set of
- Youtube-hosted video lectures that provide both the
- context of the mathematical and computational methods of
- deal.II as well as demonstrate parts of the
- tutorial. These video lectures are also reachable from
- the menu bar at the left.
- </p>
-
- <p>
- As all other documentation, the HTML pages
- of the tutorials can be generated locally on your computer and
- can then be read offline. Please follow the
- instructions in the
- <a href="../readme.html" target="body">ReadMe</a> on how to
- generate them locally.
- </p>
-
-
- <h2>Programming interface</h2>
-
- <p>
- The <a href="../doxygen/deal.II/index.html" target="_top">programming
- interface/manual</a> pages are what you will need most often as a
- reference of all classes, functions and variables in the library. They
- are extensively documented (presently more than 5000 pages if
- printed), and generated by <a href="http://www.doxygen.org/"
- target="_top">Doxygen</a>. There is also a quick link to these pages from
- the menu bar at the left.
- </p>
-
- <p>
- The documentation uses many of the features of Doxygen. In particular,
- the link takes you straight to a page that lists <i>modules</i>, a way
- to group classes with similar purposes. This may be what you are probably
- interested in when you are not yet familiar with the library. If you
- already know your way around and want to look up the signature of a
- particular member function, for example, you may go to the class view or
- choose any of the other ways in which Doxygen allows you to navigate
- through the documentation.
- </p>
-
- <p>
- Just as for the tutorials, the API docs need to be generated first,
- if you download <acronym>deal.II</acronym>. Please follow the
- instructions in the
- <a href="../readme.html" target="body">ReadMe</a> on how to do
- this.
- </p>
-
- <hr />
- <address>
- <a href="../authors.html" target="body">The deal.II Authors</a>
- $Date$
- </address>
- <div class="right">
- <a href="http://validator.w3.org/check?uri=referer" target="_top">
- <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
- <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
- </div>
-
- </body>
+<body>
+
+<h1>Information for Users</h1>
+
+<p>
+<br />
+This page gathers some information on developing programs based on
+<acronym>deal.II</acronym>, as well as on how to configure and use
+<acronym>deal.II</acronym>. At present, we have the following resources
+available:
+</p>
+
+
+<h2>Documentation</h2>
+
+<ul>
+
+<li> <p>
+ <a href="cmake.html">deal.II CMake documentation</a>:
+ This page provides extensive information about configuration and
+ installation with the CMake build system.
+
+ <li> <p><a href="cmakelists.html" target="body">Using CMake and
+ <acronym>deal.II</acronym> in a user project</a>:
+ This page covers how to use CMake in your own project.
+ An overview of how to retrieve necessary information
+ from a <acronym>deal.II</acronym> installation as well as how to
+ write a <code>CMakeLists.txt</code> for a client project is given.
+ </p>
+
+<li> <p><a href="doxygen.html">Linking your online documentation
+ to the deal.II online manual</a>: After spending a lot of time
+ writing good documentation for your code and putting it online,
+ here we explain how to put links to the deal.II online manual into
+ your documentation, so that readers can click through.
+ </p>
+
+<li> <p><a href="https://code.google.com/p/dealii/issues/list" target="_top">Bugs</a>:
+ Though well tested, <acronym>deal.II</acronym> certainly has
+ bugs. If you want to report a bug (or enhancement request),
+ go to the <a href="https://code.google.com/p/dealii/issues/list"
+ target="_top">bug tracking system</a> and enter a new ticket
+ for your issue.
+ </p>
+
+</ul>
+
+
+<h2>Tutorials</h2>
+
+<p>
+ The <a href="../doxygen/tutorial/index.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
+ programs. You can also reach the tutorial link from the
+ menu bar at the left. There is also an extensive set of
+ Youtube-hosted video lectures that provide both the
+ context of the mathematical and computational methods of
+ deal.II as well as demonstrate parts of the
+ tutorial. These video lectures are also reachable from
+ the menu bar at the left.
+</p>
+
+<p>
+ As all other documentation, the HTML pages
+ of the tutorials can be generated locally on your computer and
+ can then be read offline. Please follow the
+ instructions in the
+ <a href="../readme.html" target="body">ReadMe</a> on how to
+ generate them locally.
+</p>
+
+
+<h2>Programming interface</h2>
+
+<p>
+The <a href="../doxygen/deal.II/index.html" target="_top">programming
+ interface/manual</a> pages are what you will need most often as a
+reference of all classes, functions and variables in the library. They
+are extensively documented (presently more than 5000 pages if
+printed), and generated by <a href="http://www.doxygen.org/"
+ target="_top">Doxygen</a>. There is also a quick link to these pages from
+the menu bar at the left.
+</p>
+
+<p>
+The documentation uses many of the features of Doxygen. In particular,
+the link takes you straight to a page that lists <i>modules</i>, a way
+to group classes with similar purposes. This may be what you are probably
+interested in when you are not yet familiar with the library. If you
+already know your way around and want to look up the signature of a
+particular member function, for example, you may go to the class view or
+choose any of the other ways in which Doxygen allows you to navigate
+through the documentation.
+</p>
+
+<p>
+Just as for the tutorials, the API docs need to be generated first,
+if you download <acronym>deal.II</acronym>. Please follow the
+instructions in the
+<a href="../readme.html" target="body">ReadMe</a> on how to do
+this.
+</p>
+
+<hr />
+<address>
+ <a href="../authors.html" target="body">The deal.II Authors</a>
+ $Date$
+</address>
+<div class="right">
+ <a href="http://validator.w3.org/check?uri=referer" target="_top">
+ <img style="border:0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer" target="_top">
+ <img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
+</div>
+
+</body>
</html>
Point value=0.0333675
Estimated error=7.4912e-05
Refinement cycle: 5
- Number of degrees of freedom=1691
- Point value=0.0334104
- Estimated error=3.47976e-05
+ Number of degrees of freedom=1665
+ Point value=0.0334083
+ Estimated error=3.69111e-05
Refinement cycle: 6
- Number of degrees of freedom=4065
- Point value=0.0334315
- Estimated error=1.49476e-05
+ Number of degrees of freedom=3975
+ Point value=0.033431
+ Estimated error=1.54218e-05
Refinement cycle: 7
- Number of degrees of freedom=9113
- Point value=0.0334407
- Estimated error=6.23712e-06
+ Number of degrees of freedom=8934
+ Point value=0.0334406
+ Estimated error=6.28359e-06
Refinement cycle: 8
- Number of degrees of freedom=22303
- Point value=0.0334445
+ Number of degrees of freedom=21799
+ Point value=0.0334444
@endcode
void
local_assemble_matrix (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch_data,
- AssemblyCopyData ©_data) const;
+ AssemblyScratchData &scratch_data,
+ AssemblyCopyData ©_data) const;
void
Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
{
Threads::Task<> rhs_task = Threads::new_task (&Solver<dim>::assemble_rhs,
- *this,
- linear_system.rhs);
+ *this,
+ linear_system.rhs);
WorkStream::run(dof_handler.begin_active(),
- dof_handler.end(),
- std_cxx1x::bind(&Solver<dim>::local_assemble_matrix,
- this,
- std_cxx1x::_1,
- std_cxx1x::_2,
- std_cxx1x::_3),
- std_cxx1x::bind(&Solver<dim>::copy_local_to_global,
- this,
- std_cxx1x::_1,
- std_cxx1x::ref(linear_system)),
- AssemblyScratchData(*fe, *quadrature),
- AssemblyCopyData());
+ dof_handler.end(),
+ std_cxx1x::bind(&Solver<dim>::local_assemble_matrix,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3),
+ std_cxx1x::bind(&Solver<dim>::copy_local_to_global,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::ref(linear_system)),
+ AssemblyScratchData(*fe, *quadrature),
+ AssemblyCopyData());
rhs_task.join ();
template <int dim>
Solver<dim>::AssemblyScratchData::
AssemblyScratchData (const FiniteElement<dim> &fe,
- const Quadrature<dim> &quadrature)
- :
- fe_values (fe,
- quadrature,
- update_gradients | update_JxW_values)
+ const Quadrature<dim> &quadrature)
+ :
+ fe_values (fe,
+ quadrature,
+ update_gradients | update_JxW_values)
{}
template <int dim>
Solver<dim>::AssemblyScratchData::
AssemblyScratchData (const AssemblyScratchData &scratch_data)
- :
- fe_values (scratch_data.fe_values.get_fe(),
- scratch_data.fe_values.get_quadrature(),
- update_gradients | update_JxW_values)
+ :
+ fe_values (scratch_data.fe_values.get_fe(),
+ scratch_data.fe_values.get_quadrature(),
+ update_gradients | update_JxW_values)
{}
template <int dim>
void
Solver<dim>::local_assemble_matrix (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch_data,
- AssemblyCopyData ©_data) const
+ AssemblyScratchData &scratch_data,
+ AssemblyCopyData ©_data) const
{
const unsigned int dofs_per_cell = fe->dofs_per_cell;
const unsigned int n_q_points = quadrature->size();
for (unsigned int i=0; i<dofs_per_cell; ++i)
for (unsigned int j=0; j<dofs_per_cell; ++j)
copy_data.cell_matrix(i,j) += (scratch_data.fe_values.shape_grad(i,q_point) *
- scratch_data.fe_values.shape_grad(j,q_point) *
- scratch_data.fe_values.JxW(q_point));
+ scratch_data.fe_values.shape_grad(j,q_point) *
+ scratch_data.fe_values.JxW(q_point));
cell->get_dof_indices (copy_data.local_dof_indices);
}
LinearSystem &linear_system) const
{
for (unsigned int i=0; i<copy_data.local_dof_indices.size(); ++i)
- for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
- linear_system.matrix.add (copy_data.local_dof_indices[i],
- copy_data.local_dof_indices[j],
- copy_data.cell_matrix(i,j));
+ for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
+ linear_system.matrix.add (copy_data.local_dof_indices[i],
+ copy_data.local_dof_indices[j],
+ copy_data.cell_matrix(i,j));
}
hanging_node_constraints.clear ();
void (*mhnc_p) (const DoFHandler<dim> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
= &DoFTools::make_hanging_node_constraints;
Threads::Task<> side_task
- = Threads::new_task (mhnc_p,
- dof_handler,
- hanging_node_constraints);
+ = Threads::new_task (mhnc_p,
+ dof_handler,
+ hanging_node_constraints);
sparsity_pattern.reinit (dof_handler.n_dofs(),
- dof_handler.n_dofs(),
- dof_handler.max_couplings_between_dofs());
+ dof_handler.n_dofs(),
+ dof_handler.max_couplings_between_dofs());
DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
side_task.join();
// variables of this class; third, as arguments passed to that function.
//
// These three alternatives all have drawbacks: the third that their
- // number is not neglectable and would make calling these functions a
+ // number is not negligible and would make calling these functions a
// lengthy enterprise. The second has the drawback that it disallows
// parallelization, since the threads that will compute the error
// estimate have to have their own copies of these variables each, so
// member variables of the enclosing class will not work. The first
// approach, although straightforward, has a subtle but important
// drawback: we will call these functions over and over again, many
- // thousands of times maybe; it has now turned out that allocating
+ // thousands of times maybe; it now turns out that allocating
// vectors and other objects that need memory from the heap is an
// expensive business in terms of run-time, since memory allocation is
- // expensive when several threads are involved. In our experience, more
- // than 20 per cent of the total run time of error estimation functions
- // are due to memory allocation, if done on a per-call level. It is thus
+ // expensive when several threads are involved. It is thus
// significantly better to allocate the memory only once, and recycle
// the objects as often as possible.
//
- // What to do? Our answer is to use a variant of the third strategy,
- // namely generating these variables once in the main function of each
- // thread, and passing them down to the functions that do the actual
- // work. To avoid that we have to give these functions a dozen or so
+ // What to do? Our answer is to use a variant of the third strategy.
+ // In fact, this is exactly what the WorkStream concept is supposed to
+ // do (we have already introduced it above, but see also @ref threads).
+ // To avoid that we have to give these functions a dozen or so
// arguments, we pack all these variables into two structures, one which
// is used for the computations on cells, the other doing them on the
- // faces. Instead of many individual objects, we will then only pass one
- // such object to these functions, making their calling sequence
- // simpler.
+ // faces. Both are then joined into the WeightedResidualScratchData class
+ // that will serve as the "scratch data" class of the WorkStream concept:
struct CellData
{
FEValues<dim> fe_values;
FaceData (const FaceData &face_data);
};
-
-
struct WeightedResidualScratchData
{
WeightedResidualScratchData(const PrimalSolver<dim> &primal_solver,
};
- // Dummy structure
+ // WorkStream::run generally wants both a scratch object and a copy object.
+ // Here, for reasons similar to what we had in step-9 when discussing the
+ // computation of an approximation of the gradient, we don't actually
+ // need a "copy data" structure. Since WorkStream insists on having one of
+ // these, we just declare an empty structure that does nothing other than
+ // being there.
struct WeightedResidualCopyData
- {
- WeightedResidualCopyData() {}
- };
+ {};
- // Regarding the evaluation of the error estimator, we have two driver
- // functions that do this: the first is called to generate the cell-wise
- // estimates, and splits up the task in a number of threads each of
- // which work on a subset of the cells. The first function will run the
- // second for each of these threads:
+ // Regarding the evaluation of the error estimator, we have one driver
+ // function that uses WorkStream::run to call the second function on every
+ // cell. The concept of using SynchronousIterators was already explained
+ // in step-9:
void estimate_error (Vector<float> &error_indicators) const;
- void estimate_some (const SynchronousIterators<std_cxx1x::tuple<
- active_cell_iterator,Vector<float>::iterator> > &cell_and_error,
- WeightedResidualScratchData &scratch_data,
- WeightedResidualCopyData ©_data,
- FaceIntegrals &face_integrals) const;
-
- void dummy_copy(const WeightedResidualCopyData ©_data) const {};
+ void estimate_on_one_cell (const SynchronousIterators<std_cxx1x::tuple<
+ active_cell_iterator,Vector<float>::iterator> > &cell_and_error,
+ WeightedResidualScratchData &scratch_data,
+ WeightedResidualCopyData ©_data,
+ FaceIntegrals &face_integrals) const;
// Then we have functions that do the actual integration of the error
// representation formula. They will treat the terms on the cell
// In the implementation of this class, we first have the constructors of
// the <code>CellData</code> and <code>FaceData</code> member classes, and
// the <code>WeightedResidual</code> constructor. They only initialize
- // fields to their correct lengths, so we do not have to discuss them to
- // length.
+ // fields to their correct lengths, so we do not have to discuss them in
+ // too much detail:
template <int dim>
WeightedResidual<dim>::CellData::
CellData (const FiniteElement<dim> &fe,
template <int dim>
WeightedResidual<dim>::CellData::
- CellData (const CellData &cell_data)
+ CellData (const CellData &cell_data)
:
fe_values (cell_data.fe_values.get_fe(),
cell_data.fe_values.get_quadrature(),
const DualSolver<dim> &dual_solver,
const Vector<double> &primal_solution,
const Vector<double> &dual_weights)
- :
- cell_data (*dual_solver.fe,
- *dual_solver.quadrature,
- *primal_solver.rhs_function),
- face_data (*dual_solver.fe,
- *dual_solver.face_quadrature),
- primal_solution(primal_solution),
- dual_weights(dual_weights)
+ :
+ cell_data (*dual_solver.fe,
+ *dual_solver.quadrature,
+ *primal_solver.rhs_function),
+ face_data (*dual_solver.fe,
+ *dual_solver.face_quadrature),
+ primal_solution(primal_solution),
+ dual_weights(dual_weights)
{}
template <int dim>
WeightedResidual<dim>::WeightedResidualScratchData::
WeightedResidualScratchData (const WeightedResidualScratchData &scratch_data)
- :
- cell_data(scratch_data.cell_data),
- face_data(scratch_data.face_data),
- primal_solution(scratch_data.primal_solution),
- dual_weights(scratch_data.dual_weights)
+ :
+ cell_data(scratch_data.cell_data),
+ face_data(scratch_data.face_data),
+ primal_solution(scratch_data.primal_solution),
+ dual_weights(scratch_data.dual_weights)
{}
{
Threads::TaskGroup<> tasks;
tasks += Threads::new_task (&WeightedResidual<dim>::solve_primal_problem,
- *this);
+ *this);
tasks += Threads::new_task (&WeightedResidual<dim>::solve_dual_problem,
- *this);
+ *this);
tasks.join_all();
}
- // Now, it is becoming more interesting: the <code>refine_grid</code>
+ // Now, it is becoming more interesting: the <code>refine_grid()</code>
// function asks the error estimator to compute the cell-wise error
// indicators, then uses their absolute values for mesh refinement.
template <int dim>
// As for the actual computation of error estimates, let's start with the
// function that drives all this, i.e. calls those functions that actually
// do the work, and finally collects the results.
-
template <int dim>
void
WeightedResidual<dim>::
// afterwards when looping over all cells a second time.
//
// We initialize this map already with a value of -1e20 for all faces,
- // since this value will strike in the results if something should go
+ // since this value will stand out in the results if something should go
// wrong and we fail to compute the value for a face for some
- // reason. Secondly, we initialize the map once before we branch to
- // different threads since this way the map's structure is no more
- // modified by the individual threads, only existing entries are set to
- // new values. This relieves us from the necessity to synchronise the
+ // reason. Secondly, this initialization already makes the std::map
+ // object allocate all objects it may possibly need. This is important
+ // since we will write into this structure from parallel threads,
+ // and doing so would not be thread-safe if the map needed to allocate
+ // memory and thereby reshape its data structures. In other words, the
+ // initial initialization relieves us from the necessity to synchronize the
// threads through a mutex each time they write to (and modify the
// structure of) this map.
FaceIntegrals face_integrals;
++face_no)
face_integrals[cell->face(face_no)] = -1e20;
- // Then set up a vector with error indicators. Reserve one slot for
- // each cell and set it to zero.
+ // Then set up a vector with error indicators and reserve one slot for
+ // each cell and set it to zero. With this, we can then set up the
+ // parallel iterator range just as we did in step-9, and hand it
+ // all off to WorkStream::run to compute the estimators for all
+ // cells in parallel:
error_indicators.reinit (dual_solver.dof_handler
.get_tria().n_active_cells());
- typedef std_cxx1x::tuple<active_cell_iterator,Vector<float>::iterator> Iterators;
- SynchronousIterators<Iterators> cell_and_error_begin(Iterators (
- dual_solver.dof_handler.begin_active(),error_indicators.begin()));
- SynchronousIterators<Iterators> cell_and_error_end(Iterators (
- dual_solver.dof_handler.end(),error_indicators.begin()));
-
- WeightedResidualScratchData scratch_data(primal_solver,dual_solver,primal_solution,dual_weights);
- WeightedResidualCopyData copy_data;
-
- // Compute the error formula on all the cells
- WorkStream::run(cell_and_error_begin,cell_and_error_end,
- std_cxx1x::bind(&WeightedResidual<dim>::estimate_some,this,std_cxx1x::_1,
- std_cxx1x::_2,std_cxx1x::_3,std_cxx1x::ref(face_integrals)),
- std_cxx1x::bind(&WeightedResidual<dim>::dummy_copy,this,std_cxx1x::_1),
- scratch_data,copy_data);
+ typedef
+ std_cxx1x::tuple<active_cell_iterator,Vector<float>::iterator>
+ IteratorTuple;
+
+ SynchronousIterators<IteratorTuple>
+ cell_and_error_begin(IteratorTuple (dual_solver.dof_handler.begin_active(),
+ error_indicators.begin()));
+ SynchronousIterators<IteratorTuple>
+ cell_and_error_end (IteratorTuple (dual_solver.dof_handler.end(),
+ error_indicators.begin()));
+
+ WorkStream::run(cell_and_error_begin,
+ cell_and_error_end,
+ std_cxx1x::bind(&WeightedResidual<dim>::estimate_on_one_cell,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3,
+ std_cxx1x::ref(face_integrals)),
+ std_cxx1x::function<void (const WeightedResidualCopyData &)>(),
+ WeightedResidualScratchData (primal_solver,
+ dual_solver,
+ primal_solution,
+ dual_weights),
+ WeightedResidualCopyData());
// Once the error contributions are computed, sum them up. For this,
// note that the cell terms are already set, and that only the edge
}
- // @sect4{Estimating on a subset of cells}
+ // @sect4{Estimating on a single cell}
// Next we have the function that is called to estimate the error on a
- // subset of cells. The function may be called multiple times if the library was
+ // single cell. The function may be called multiple times if the library was
// configured to use multithreading. Here it goes:
template <int dim>
void
WeightedResidual<dim>::
- estimate_some (const SynchronousIterators<std_cxx1x::tuple<
- active_cell_iterator,Vector<float>::iterator> > &cell_and_error,
- WeightedResidualScratchData &scratch_data,
- WeightedResidualCopyData ©_data,
- FaceIntegrals &face_integrals) const
+ estimate_on_one_cell (const SynchronousIterators<std_cxx1x::tuple<
+ active_cell_iterator,Vector<float>::iterator> > &cell_and_error,
+ WeightedResidualScratchData &scratch_data,
+ WeightedResidualCopyData ©_data,
+ FaceIntegrals &face_integrals) const
{
// First task on each cell is to compute the cell residual
// contributions of this cell, and put them into the
// <code>error_indicators</code> variable:
active_cell_iterator cell = std_cxx1x::get<0>(cell_and_error.iterators);
-
+
integrate_over_cell (cell_and_error,
scratch_data.primal_solution,
scratch_data.dual_weights,
scratch_data.cell_data);
-
+
// After computing the cell terms, turn to the face terms. For this,
// loop over all faces of the present cell, and see whether
// something needs to be computed on it:
where the rank-4 tensor $I_\Pi=I_\Pi(\varepsilon^D(\mathbf u^{i-1}))$ given by
@f{align}
I_\Pi = \begin{cases}
- C_{\mu} + C_{\kappa}, & \hspace{-8em}\hfill \text{if } \vert C\varepsilon^D(\mathbf u^{i-1}) \vert \leq \sigma_0,
+ C_{\mu} + C_{\kappa}, & \hspace{-8em} \text{if } \vert C\varepsilon^D(\mathbf u^{i-1}) \vert \leq \sigma_0,
\\
\frac{\gamma^{\text{iso}}}{2\mu + \gamma^{\text{iso}}} C_{\mu} + \frac{\left(1-\frac{\gamma^{\text{iso}}}{2\mu + \gamma^{\text{iso}}}\right)\sigma_0}{\vert C\varepsilon^D(\mathbf u^{i-1}) \vert}\left(C_{\mu} -
2\mu\dfrac{C\varepsilon^D(\mathbf u^{i-1})\otimes C\varepsilon^D(\mathbf
from the undisplaced configuration of the body.
<li> If $\mathcal{A}_{i+1} = \mathcal{A}_k$ and $\left\|
- {\hat R}\left({\mathbf u}^{i}\right)\right) \right\|_{\ell_2} < \delta$ then stop, else set $i=i+1$ and go to
+ {\hat R}\left({\mathbf u}^{i}\right) \right\|_{\ell_2} < \delta$ then stop, else set $i=i+1$ and go to
step (1). This step ensures that we only stop iterations if both the correct
active set has been found and the plasticity has been iterated to sufficient
accuracy.
The above procedure also has a linear algebra interpretation and is referred to
as static condensation. Let us write the complete linear system associated to
-the HDG problem as a block system with the discrete DG variables <i>U</i> as
+the HDG problem as a block system with the discrete DG variables $U$ as
first block and the skeleton variables $\Lambda$ as the second block:
@f{eqnarray*}
\begin{pmatrix} A & B \\ C & D \end{pmatrix}
=
\begin{pmatrix} F \\ G \end{pmatrix}.
@f}
-Our aim is now to eliminate the <i>U</i> block with a Schur complement
+Our aim is now to eliminate the $U$ block with a Schur complement
approach similar to step-20, which results in the following two steps:
@f{eqnarray*}
(D - C A^{-1} B) \Lambda &=& G - C A^{-1} F, \\
block diagonal matrix where each block corresponds to one cell and is
therefore easy enough to invert.
The coupling to other cells is introduced by the matrices
-<i>B</i> and <i>C</i> over the skeleton variable. The block-diagonality of
-<i>A</i> and the structure in <i>B</i> and <i>C</i> allow us to invert the
-matrix <i>A</i> element by element (the local solution of the Dirichlet
+$B$ and $C$ over the skeleton variable. The block-diagonality of
+$A$ and the structure in $B$ and $C$ allow us to invert the
+matrix $A$ element by element (the local solution of the Dirichlet
problem) and subtract $CA^{-1}B$ from $D$. The steps in the Dirichlet-to-Neumann map concept hence correspond to
<ol>
<li> constructing the Schur complement matrix $D-C A^{-1} B$ and right hand side $G - C A^{-1} F$ <i>locally on each cell</i>
and inserting the contribution into the global trace matrix in the usual way,
<li> solving the Schur complement system for $\Lambda$, and
- <li> solving for <i>U</i> using the second equation, given $\Lambda$.
+ <li> solving for $U$ using the second equation, given $\Lambda$.
</ol>
from the DG method, with jumps of the solution over the cell boundaries.
In the equation above, the space $\mathcal {W}_h^{p}$ for the scalar variable
-<i>u<sub>h</sub></i> is defined as the space of functions that are tensor
-product polynomials of degree <i>p</i> on each cell and discontinuous over the
+$u_h$ is defined as the space of functions that are tensor
+product polynomials of degree $p$ on each cell and discontinuous over the
element boundaries $\mathcal Q_{-p}$, i.e., the space described by
<code>FE_DGQ<dim>(p)</code>. The space for the gradient or flux variable
-<b>q</b><i><sub>h</sub></i> is a vector element space where each component is
+$\mathbf{q}_i$ is a vector element space where each component is
a locally polynomial and discontinuous $\mathcal Q_{-p}$. In the code below,
we collect these two local parts together in one FESystem where the first @p
dim components denote the gradient part and the last scalar component
constructing an enriched solution that gains accuracy. This post-processing
takes the HDG solution in an element-by-element fashion and combines it such
that one can get $\mathcal O(h^{p+2})$ order of accuracy when using
-polynomials of degree <i>p</i>. For this to happen, there are two necessary
+polynomials of degree $p$. For this to happen, there are two necessary
ingredients:
<ol>
<li> The computed solution gradient $\mathbf{q}_h$ converges at optimal rate,
i.e., $\mathcal{O}(h^{p+1})$.
<li> The average of the scalar part of the solution, <i>u<sub>h</sub></i>,
- on each cell <i>K</i> super-converges at rate $\mathcal{O}(h^{p+2})$.
+ on each cell $K$ super-converges at rate $\mathcal{O}(h^{p+2})$.
</ol>
We now introduce a new variable $u_h^* \in \mathcal{V}_h^{p+1}$, which we find
by minimizing the expression $|\kappa \nabla u_h^* + \mathbf{q}_h|^2$ over the cell
-<i>K</i> under the constraint $\left(1, u_h^*\right)_K &=& \left(1,
+$K$ under the constraint $\left(1, u_h^*\right)_K = \left(1,
u_h\right)_K$. The constraint is necessary because the minimization
functional does not determine the constant part of $u_h^*$. This
translates to the following system of equations:
@f}
Since we test by the whole set of basis functions in the space of tensor
-product polynomials of degree <i>p</i>+1 in the second set of equations, this
+product polynomials of degree $p+1$ in the second set of equations, this
is an overdetermined system with one more equation than unknowns. We fix this
in the code below by omitting one of these equations (since the rows in the
Laplacian are linearly dependent when representing a constant function). As we
For this tutorial program, we consider almost the same test case as in
step-7. The computational domain is $\Omega := [-1,1]^d$ and the exact
solution corresponds to the one in step-7, except for a scaling. We use the
-following source centers <i>x<sub>i</sub></i> for the exponentials
+following source centers $x_i$ for the exponentials
<ul>
<li> 1D: $\{x_i\}^1 = \{ -\frac{1}{3}, 0, \frac{1}{3} \}$,
<li> 2D: $\{\mathbf{x}_i\}^2 = \{ (-\frac{1}{2},\frac{1}{2}),
<h3>Program output</h3>
We first have a look at the output generated by the program when run in 2D. In
-the four images below, we show the solution for polynomial degree <i>p</i>=1
+the four images below, we show the solution for polynomial degree $p=1$
and cycles 2, 3, 4, and 8 of the program. In the plots, we overlay the data
generated from the internal data (DG part) with the skeleton part ($\hat{u}$)
into the same plot. We had to generate two different data sets because cells
</tr>
</table>
-Finally, we look at the solution for <i>p</i>=3 at cycle 2. Despite the coarse
+Finally, we look at the solution for $p=3$ at cycle 2. Despite the coarse
mesh with only 64 cells, the post-processed solution is similar in quality
to the linear solution (not post-processed) at cycle 8 with 4,096
cells. This clearly shows the superiority of high order methods for smooth
variable and the gradient variable is apparent, as is the cubic rate for the
postprocessed scalar variable in the $L_2$ norm. Note this distinctive
feature of an HDG solution. In typical continuous finite elements, the
-gradient of the solution of order <i>p</i> converges at rate <i>p</i> only, as
-opposed to <i>p</i>+1 for the actual solution. Even though superconvergence
+gradient of the solution of order $p$ converges at rate $p$ only, as
+opposed to $p+1$ for the actual solution. Even though superconvergence
results for finite elements are also available (e.g. superconvergent patch
recovery first introduced by Zienkiewicz and Zhu), these are typically limited
to structured meshes and other special cases. For Q3 HDG variables, the scalar
</table>
The results in the graphs show that the HDG method is slower than continuous
-finite elements at <i>p</i>=1, about equally fast for cubic elements and
+finite elements at $p=1$, about equally fast for cubic elements and
faster for sixth order elements. However, we have seen above that the HDG
method actually produces solutions which are more accurate than what is
represented in the original variables. Therefore, in the next two plots below
we instead display the error of the post-processed solution for HDG (denoted
by $p=1^*$ for example). We now see a clear advantage of HDG for the same
-amount of work for both <i>p</i>=3 and <i>p</i>=6, and about the same quality
-for <i>p</i>=1.
+amount of work for both $p=3$ and $p=6$, and about the same quality
+for $p=1$.
<table align="center" border="1" cellspacing="3" cellpadding="3">
<tr>
</table>
Since the HDG method actually produces results converging as
-<i>h</i><sup><i>p</i>+2</sup>, we should compare it to a continuous Galerkin
+$h^{p+2}$, we should compare it to a continuous Galerkin
solution with the same asymptotic convergence behavior, i.e., FE_Q with degree
-<i>p</i>+1. If we do this, we get the convergence curves below. We see that
+$p+1$. If we do this, we get the convergence curves below. We see that
CG with second order polynomials is again clearly better than HDG with
linears. However, the advantage of HDG for higher orders remains.
The results are in line with properties of DG methods in general: Best
performance is typically not achieved for linear elements, but rather at
-somewhat higher order, usually around <i>p</i>=3. This is because of a
+somewhat higher order, usually around $p=3$. This is because of a
volume-to-surface effect for discontinuous solutions with too much of the
solution living on the surfaces and hence duplicating work when the elements
are linear. Put in other words, DG methods are often most efficient when used
We now show the same figures in 3D: The first row shows the number of degrees
of freedom and computing time versus the $L_2$ error in the scalar variable
-<i>u</i> for CG and HDG at order <i>p</i>, the second row shows the
+$u$ for CG and HDG at order $p$, the second row shows the
post-processed HDG solution instead of the original one, and the third row
-compares the post-processed HDG solution with CG at order <i>p</i>+1. In 3D,
+compares the post-processed HDG solution with CG at order $p+1$. In 3D,
the volume-to-surface effect makes the cost of HDG somewhat higher and the CG
solution is clearly better than HDG for linears by any metric. For cubics, HDG
and CG are of similar quality, whereas HDG is again more efficient for sixth
order polynomials. One can alternatively also use the combination of FE_DGP
and FE_FaceP instead of (FE_DGQ, FE_FaceQ), which do not use tensor product
-polynomials of degree <i>p</i> but Legendre polynomials of <i>complete</i>
-degree <i>p</i>. There are fewer degrees of freedom on the skeleton variable
+polynomials of degree $p$ but Legendre polynomials of <i>complete</i>
+degree $p$. There are fewer degrees of freedom on the skeleton variable
for FE_FaceP for a given mesh size, but the solution quality (error vs. number
of DoFs) is very similar to the results for FE_FaceQ.
both without particular tuning of the AMG parameters on any of them) to give a
fair picture of the cost versus accuracy of two methods, on a toy example. It
should be noted however that geometric multigrid (GMG) for continuous finite elements is about a
-factor four to five faster for <i>p</i>=3 and <i>p</i>=6. The authors of this
+factor four to five faster for $p=3$ and $p=6$. The authors of this
tutorial have not seen similarly advanced solvers for the HDG linear
systems. Also, there are other implementation aspects for CG available such as
fast matrix-free approaches as shown in step-37 that make higher order
Number of active cells: 643
Number of degrees of freedom: 793
Cycle 2:
- Number of active cells: 1663
- Number of degrees of freedom: 1946
+ Number of active cells: 1669
+ Number of degrees of freedom: 1950
Cycle 3:
- Number of active cells: 4219
- Number of degrees of freedom: 4905
+ Number of active cells: 4231
+ Number of degrees of freedom: 4923
Cycle 4:
- Number of active cells: 10708
- Number of degrees of freedom: 12128
+ Number of active cells: 10753
+ Number of degrees of freedom: 12175
Cycle 5:
- Number of active cells: 26908
- Number of degrees of freedom: 29698
+ Number of active cells: 27004
+ Number of degrees of freedom: 29810
@endcode
As can be seen, quite a number of cells is used on the finest level to
resolve the features of the solution. The final grid showing this is
Note that the solution is created by that part that is transported
-along the wiggled advection field from the left and lower boundaries
+along the wiggly advection field from the left and lower boundaries
to the top right, and the part that is created by the source in the
lower left corner, and the results of which are also transported
along. The grid shown above is well-adapted to resolve these
// @sect3{AdvectionProblem class declaration}
// Following we declare the main class of this program. It is very much
- // alike the main classes of previous examples, so we again only comment on
+ // like the main classes of previous examples, so we again only comment on
// the differences.
template <int dim>
class AdvectionProblem
void assemble_system ();
void local_assemble_system (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch,
- AssemblyCopyData ©_data);
+ AssemblyScratchData &scratch,
+ AssemblyCopyData ©_data);
void copy_local_to_global (const AssemblyCopyData ©_data);
// of the mesh size, as described in the introduction. This class is a
// simple version of the <code>DerivativeApproximation</code> class in the
// library, that uses similar techniques to obtain finite difference
- // approximations of the gradient of a finite element field, or if higher
+ // approximations of the gradient of a finite element field, or of higher
// derivatives.
//
// The class has one public static function <code>estimate</code> that is
- // called to compute a vector of error indicators, and one private function
- // that does the actual work on an interval of all active cells. The latter
- // is called by the first one in order to be able to do the computations in
- // parallel if your computer has more than one processor. While the first
- // function accepts as parameter a vector into which the error indicator is
- // written for each cell. This vector is passed on to the second function
- // that actually computes the error indicators on some cells, and the
- // respective elements of the vector are written. By the way, we made it
- // somewhat of a convention to use vectors of floats for error indicators
- // rather than the common vectors of doubles, as the additional accuracy is
- // not necessary for estimated values.
+ // called to compute a vector of error indicators, and a few private functions
+ // that do the actual work on all active cells. As in other parts of the
+ // library, we follow an informal convention to use vectors of floats for
+ // error indicators rather than the common vectors of doubles, as the
+ // additional accuracy is not necessary for estimated values.
//
// In addition to these two functions, the class declares two exceptions
// which are raised when a cell has no neighbors in each of the space
// more common case of invalid parameters to a function, namely a vector of
// wrong size.
//
- // Two annotations to this class are still in order: the first is that the
- // class has no non-static member functions or variables, so this is not
- // really a class, but rather serves the purpose of a <code>namespace</code>
- // in C++. The reason that we chose a class over a namespace is that this
- // way we can declare functions that are private, i.e. visible to the
- // outside world but not callable. This can be done with namespaces as well,
- // if one declares some functions in header files in the namespace and
- // implements these and other functions in the implementation file. The
- // functions not declared in the header file are still in the namespace but
- // are not callable from outside. However, as we have only one file here, it
- // is not possible to hide functions in the present case.
+ // Two other comments: first, the class has no non-static member functions
+ // or variables, so this is not really a class, but rather serves the
+ // purpose of a <code>namespace</code> in C++. The reason that we chose a
+ // class over a namespace is that this way we can declare functions that are
+ // private. This can be done with namespaces as well, if one declares some
+ // functions in header files in the namespace and implements these and other
+ // functions in the implementation file. The functions not declared in the
+ // header file are still in the namespace but are not callable from
+ // outside. However, as we have only one file here, it is not possible to
+ // hide functions in the present case.
//
- // The second is that the dimension template parameter is attached to the
- // function rather than to the class itself. This way, you don't have to
- // specify the template parameter yourself as in most other cases, but the
- // compiler can figure its value out itself from the dimension of the DoF
- // handler object that one passes as first argument.
+ // The second comment is that the dimension template parameter is attached
+ // to the function rather than to the class itself. This way, you don't have
+ // to specify the template parameter yourself as in most other cases, but
+ // the compiler can figure its value out itself from the dimension of the
+ // DoF handler object that one passes as first argument.
//
- // Finally note that the <code>IndexInterval</code> typedef is introduced as
- // a convenient abbreviation for an otherwise lengthy type name.
+ // Before jumping into the fray with the implementation, let us also comment
+ // on the parallelization strategy. We have already introduced the necessary
+ // framework for using the WorkStream concept in the declaration of the main
+ // class of this program above. We will use it again here. In the current
+ // context, this means that we have to define (i) classes for scratch and
+ // copy objects, (ii) a function that does the local computation on one
+ // cell, and (iii) a function that copies the local result into a global
+ // object. Given this general framework, we will, however, deviate from it a
+ // bit. In particular, WorkStream was generally invented for cases where
+ // each local computation on a cell <i>adds</i> to a global object -- for
+ // example, when assembling linear systems where we add local contributions
+ // into a global matrix and right hand side. Here, however, the situation is
+ // slightly different: we compute contributions from every cell
+ // individually, but then all we need to do is put them into an element of
+ // an output vector that is unique to each cell. Consequently, there is no
+ // risk that the write operations from two cells might conflict, and the
+ // elaborate machinery of WorkStream to avoid conflicting writes is not
+ // necessary. Consequently, what we will do is this: We still need a scratch
+ // object that holds, for example, the FEValues object. However, we only
+ // create an fake, empty copy data structure. Likewise, we do need the
+ // function that computes local contributions, but since it can already put
+ // the result into its final location, we do not need a copy-local-to-global
+ // function and will instead give the WorkStream::run function an empty
+ // function object -- the equivalent to a NULL function pointer.
+ //
+ // The second idea to make this approach work is this: If we want to write
+ // the result into its final destination right away, then the local worker
+ // function needs to already know where this destination is. Here, this is
+ // an element of a vector -- but which element is something that the local
+ // worker function (or, if we wanted to use one, a copy-local-to-global
+ // function) can not determine easily just knowing an iterator to a cell it
+ // is supposed to work on. Consequently, in addition to a cell, we need to
+ // pass a second piece of identifying information along: the element of the
+ // output vector to write into. What this means is that the work items are
+ // identified by two iterators: to a cell, and to an output vector
+ // element. Moving from one work item to the next requires incrementing both
+ // iterators. deal.II has a class for this, called SynchronousIterators,
+ // that takes a tuple of iterator types as arguments and stores an iterator
+ // of each type. Whenever the SynchronousIterators object is incremented, it
+ // increments the stored iterators in turn. Thus, this class is exactly what
+ // we need to do our work, and we consequently use it as the first argument
+ // of the worker function. We will further down below show how to create
+ // such an object.
class GradientEstimation
{
public:
private:
template <int dim>
- struct EstimateScratchData
+ struct EstimateScratchData
{
EstimateScratchData (const FiniteElement<dim> &fe,
const Vector<double> &solution);
Vector<double> solution;
};
- // There is nothing to copy but WorkStream requires a CopyData structure
- template <int dim>
- struct EstimateCopyData
- {
- EstimateCopyData () {}
- };
+ struct EstimateCopyData
+ {};
template <int dim>
- static void estimate_cell (
- const SynchronousIterators<std_cxx1x::tuple<typename DoFHandler<dim>::active_cell_iterator,
- Vector<float>::iterator> > &cell,
- EstimateScratchData<dim> &scratch_data,
- const EstimateCopyData<dim> ©_data);
- // There is nothing to copy but WorkStream required a copy function
- template <int dim>
- static void dummy_copy(const EstimateCopyData<dim> ©_data) {}
+ static
+ void estimate_cell (const SynchronousIterators<std_cxx1x::tuple<typename DoFHandler<dim>::active_cell_iterator,
+ Vector<float>::iterator> > &cell,
+ EstimateScratchData<dim> &scratch_data,
+ const EstimateCopyData ©_data);
};
// the function <code>setup_system</code> follow the same pattern that was
// used previously, so we need not comment on these three function:
template <int dim>
- AdvectionProblem<dim>::AdvectionProblem () :
+ AdvectionProblem<dim>::AdvectionProblem ()
+ :
dof_handler (triangulation),
fe(1)
{}
void AdvectionProblem<dim>::assemble_system ()
{
WorkStream::run(dof_handler.begin_active(),
- dof_handler.end(),
- *this,
- &AdvectionProblem::local_assemble_system,
- &AdvectionProblem::copy_local_to_global,
- AssemblyScratchData(fe),
- AssemblyCopyData());
+ dof_handler.end(),
+ *this,
+ &AdvectionProblem::local_assemble_system,
+ &AdvectionProblem::copy_local_to_global,
+ AssemblyScratchData(fe),
+ AssemblyCopyData());
// After the matrix has been assembled in parallel, we still have to
template <int dim>
AdvectionProblem<dim>::AssemblyScratchData::
AssemblyScratchData (const FiniteElement<dim> &fe)
- :
- fe_values (fe,
- QGauss<dim>(2),
- update_values | update_gradients |
- update_quadrature_points | update_JxW_values),
- fe_face_values (fe,
- QGauss<dim-1>(2),
- update_values | update_quadrature_points |
- update_JxW_values | update_normal_vectors)
+ :
+ fe_values (fe,
+ QGauss<dim>(2),
+ update_values | update_gradients |
+ update_quadrature_points | update_JxW_values),
+ fe_face_values (fe,
+ QGauss<dim-1>(2),
+ update_values | update_quadrature_points |
+ update_JxW_values | update_normal_vectors)
{}
template <int dim>
AdvectionProblem<dim>::AssemblyScratchData::
AssemblyScratchData (const AssemblyScratchData &scratch_data)
- :
- fe_values (scratch_data.fe_values.get_fe(),
- scratch_data.fe_values.get_quadrature(),
- update_values | update_gradients |
- update_quadrature_points | update_JxW_values),
- fe_face_values (scratch_data.fe_face_values.get_fe(),
- scratch_data.fe_face_values.get_quadrature(),
- update_values | update_quadrature_points |
- update_JxW_values | update_normal_vectors)
+ :
+ fe_values (scratch_data.fe_values.get_fe(),
+ scratch_data.fe_values.get_quadrature(),
+ update_values | update_gradients |
+ update_quadrature_points | update_JxW_values),
+ fe_face_values (scratch_data.fe_face_values.get_fe(),
+ scratch_data.fe_face_values.get_quadrature(),
+ update_values | update_quadrature_points |
+ update_JxW_values | update_normal_vectors)
{}
void
AdvectionProblem<dim>::
local_assemble_system (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch_data,
- AssemblyCopyData ©_data)
+ AssemblyScratchData &scratch_data,
+ AssemblyCopyData ©_data)
{
// First of all, we will need some objects that describe boundary values,
// right hand side function and the advection field. As we will only
{
for (unsigned int i=0; i<copy_data.local_dof_indices.size(); ++i)
{
- for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
- system_matrix.add (copy_data.local_dof_indices[i],
- copy_data.local_dof_indices[j],
- copy_data.cell_matrix(i,j));
+ for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
+ system_matrix.add (copy_data.local_dof_indices[i],
+ copy_data.local_dof_indices[j],
+ copy_data.cell_matrix(i,j));
- system_rhs(copy_data.local_dof_indices[i]) += copy_data.cell_rhs(i);
+ system_rhs(copy_data.local_dof_indices[i]) += copy_data.cell_rhs(i);
}
}
data_out.add_data_vector (solution, "solution");
data_out.build_patches ();
- std::ofstream output ("final-solution.gmv");
- data_out.write_gmv (output);
+ std::ofstream output ("final-solution.vtk");
+ data_out.write_vtk (output);
}
// @sect3{GradientEstimation class implementation}
- // ScratchData used by estimate_cell
+ // Now for the implementation of the <code>GradientEstimation</code> class.
+ // Let us start by defining constructors for the
+ // <code>EstimateScratchData</code> class used by the
+ // <code>estimate_cell()</code> function:
template <int dim>
- GradientEstimation::EstimateScratchData<dim>
- ::EstimateScratchData (const FiniteElement<dim> &fe,
+ GradientEstimation::EstimateScratchData<dim>::
+ EstimateScratchData (const FiniteElement<dim> &fe,
const Vector<double> &solution)
- :
- fe_midpoint_value(fe,
- QMidpoint<dim> (),
- update_values | update_quadrature_points),
- solution(solution)
+ :
+ fe_midpoint_value(fe,
+ QMidpoint<dim> (),
+ update_values | update_quadrature_points),
+ solution(solution)
{}
-
- // ScratchData used by estimate_cell
template <int dim>
- GradientEstimation::EstimateScratchData<dim>
- ::EstimateScratchData(const EstimateScratchData &scratch_data)
- :
- fe_midpoint_value(scratch_data.fe_midpoint_value.get_fe(),
- scratch_data.fe_midpoint_value.get_quadrature(),
- update_values | update_quadrature_points),
- solution(scratch_data.solution)
+ GradientEstimation::EstimateScratchData<dim>::
+ EstimateScratchData(const EstimateScratchData &scratch_data)
+ :
+ fe_midpoint_value(scratch_data.fe_midpoint_value.get_fe(),
+ scratch_data.fe_midpoint_value.get_quadrature(),
+ update_values | update_quadrature_points),
+ solution(scratch_data.solution)
{}
- // Now for the implementation of the <code>GradientEstimation</code>
+ // Next for the implementation of the <code>GradientEstimation</code>
// class. The first function does not much except for delegating work to the
- // other function:
+ // other function, but there is a bit of setup at the top.
+ //
+ // Before starting with the work, we check that the vector into which the
+ // results are written has the right size. It is a common error that such
+ // parameters have the wrong size, but the resulting damage by not
+ // catching these errors are very subtle as they are usually corruption of
+ // data somewhere in memory. Often, the problems emerging from this are
+ // not reproducible, and it is well worth the effort to
+ // check for such things.
+ //
+ // The second piece is to set up the iterator that goes in lockstep over the
+ // cells of the domain and the corresponding elements of the output vector
+ // (see above where we introduced the <code>SynchronousIterators</code>
+ // class). We can abbreviate the process slightly by introducing a
+ // <code>typedef</code> that denotes a pair of iterators. This being set up,
+ // we can hand the whole thing off to WorkStream::run, keeping in mind that
+ // we do not need a copy-local-to-global function here but can get away by
+ // simply using a default-constructed function object (the equivalent to a
+ // NULL function pointer).
template <int dim>
void
GradientEstimation::estimate (const DoFHandler<dim> &dof_handler,
const Vector<double> &solution,
Vector<float> &error_per_cell)
{
- // Before starting with the work, we check that the vector into which the
- // results are written, has the right size. It is a common error that such
- // parameters have the wrong size, but the resulting damage by not
- // catching these errors are very subtle as they are usually corruption of
- // data somewhere in memory. Often, the problems emerging from this are
- // not reproducible, and we found that it is well worth the effort to
- // check for such things.
Assert (error_per_cell.size() == dof_handler.get_tria().n_active_cells(),
ExcInvalidVectorLength (error_per_cell.size(),
dof_handler.get_tria().n_active_cells()));
- // In the same way as before, we use a <code>Threads::ThreadGroup</code>
- // object to collect the descriptor objects of different threads. Note
- // that as the function called is not a member function, but rather a
- // static function, we need not (and can not) pass a <code>this</code>
- // pointer to the <code>new_thread</code> function in this case.
- //
- // Taking pointers to templated functions seems to be notoriously
- // difficult for many compilers (since there are several functions with
- // the same name -- just as with overloaded functions). It therefore
- // happens quite frequently that we can't directly insert taking the
- // address of a function in the call to <code>encapsulate</code> for one
- // or the other compiler, but have to take a temporary variable for that
- // purpose. Here, in this case, Compaq's <code>cxx</code> compiler choked
- // on the code so we use this workaround with the function pointer:
- void (*estimate_cell_ptr) (const SynchronousIterators<std_cxx1x::tuple<
- typename DoFHandler<dim>::active_cell_iterator,Vector<float>::iterator> > &cell,
- EstimateScratchData<dim> &scratch_data,
- const EstimateCopyData<dim> ©_data)
- = &GradientEstimation::template estimate_cell<dim>;
-
- void (*dummy_copy) (const EstimateCopyData<dim> ©_data)
- = &GradientEstimation::template dummy_copy<dim>;
-
typedef std_cxx1x::tuple<typename DoFHandler<dim>::active_cell_iterator,Vector<float>::iterator>
- Iterators;
- SynchronousIterators<Iterators> begin_sync_it(Iterators(dof_handler.begin_active(),
- error_per_cell.begin()));
- SynchronousIterators<Iterators> end_sync_it(Iterators(dof_handler.end(),error_per_cell.end()));
-
- WorkStream::run(begin_sync_it,end_sync_it,
- estimate_cell_ptr,
- dummy_copy,
- EstimateScratchData<dim> (dof_handler.get_fe(),solution),
- EstimateCopyData<dim> ());
-
- // Note that if the value of the variable
- // <code>multithread_info.n_threads()</code> was one, or if the
- // library was not configured to use threads, then the sequence of
- // commands above reduced to a complicated way to simply call the
- // <code>estimate_interval</code> function with the whole range of cells
- // to work on. However, using the way above, we are able to write the
- // program such that it makes no difference whether we presently work with
- // multiple threads or in single-threaded mode, thus eliminating the need
- // to write code included in conditional preprocessor sections.
+ IteratorTuple;
+
+ SynchronousIterators<IteratorTuple>
+ begin_sync_it (IteratorTuple (dof_handler.begin_active(),
+ error_per_cell.begin())),
+ end_sync_it (IteratorTuple (dof_handler.end(),
+ error_per_cell.end()));
+
+ WorkStream::run (begin_sync_it,
+ end_sync_it,
+ &GradientEstimation::template estimate_cell<dim>,
+ std_cxx1x::function<void (const EstimateCopyData &)> (),
+ EstimateScratchData<dim> (dof_handler.get_fe(),
+ solution),
+ EstimateCopyData ());
}
// Following now the function that actually computes the finite difference
// approximation to the gradient. The general outline of the function is to
- // loop over all the cells in the range of iterators designated by the third
- // argument, and on each cell first compute the list of active neighbors of
- // the present cell and then compute the quantities described in the
- // introduction for each of the neighbors. The reason for this order is that
- // it is not a one-liner to find a given neighbor with locally refined
- // meshes. In principle, an optimized implementation would find neighbors
- // and the quantities depending on them in one step, rather than first
- // building a list of neighbors and in a second step their contributions.
+ // first compute the list of active neighbors of the present cell and then
+ // compute the quantities described in the introduction for each of the
+ // neighbors. The reason for this order is that it is not a one-liner to
+ // find a given neighbor with locally refined meshes. In principle, an
+ // optimized implementation would find neighbors and the quantities
+ // depending on them in one step, rather than first building a list of
+ // neighbors and in a second step their contributions but we will gladly
+ // leave this as an exercise. As discussed before, the worker function
+ // passed to WorkStream::run works on "scratch" objects that keep all
+ // temporary objects. This way, we do not need to create and initialize
+ // objects that are expensive to initialize within the function that does
+ // the work, every time it is called for a given cell. Such an argument is
+ // passed as the second argument. The third argument would be a "copy-data"
+ // object (see @ref threads for more information) but we do not actually use
+ // any of these here. Because WorkStream::run insists on passing three
+ // arguments, we declare this function with three arguments, but simply
+ // ignore the last one.
+ //
+ // (This is unsatisfactory from an esthetic perspective. It can be avoided,
+ // at the cost of some other trickery. If you allow, let us here show
+ // how. First, assume that we had declared this function to only take two
+ // arguments by omitting the unused last one. Now, WorkStream::run still
+ // wants to call this function with three arguments, so we need to find a
+ // way to "forget" the third argument in the call. Simply passing
+ // WorkStream::run the pointer to the function as we do above will not do
+ // this -- the compiler will complain that a function declared to have two
+ // arguments is called with three arguments. However, we can do this by
+ // passing the following as the third argument when calling WorkStream::run
+ // above:
+ // @code
+ // std_cxx1x::function<void (const SynchronousIterators<IteratorTuple> &,
+ // EstimateScratchData<dim> &,
+ // EstimateCopyData &)>
+ // (std_cxx1x::bind (&GradientEstimation::template estimate_cell<dim>,
+ // std_cxx1x::_1,
+ // std_cxx1x::_2))
+ // @endcode
+ // This creates a function object taking three arguments, but when it calls
+ // the underlying function object, it simply only uses the first and second
+ // argument -- we simply "forget" to use the third argument :-)
+ // In the end, this isn't completely obvious either, and so we didn't implement
+ // it, but hey -- it can be done!)
//
// Now for the details:
template <int dim>
void
- GradientEstimation::estimate_cell (const SynchronousIterators<std_cxx1x::tuple<
- typename DoFHandler<dim>::active_cell_iterator,Vector<float>::iterator> > &cell,
- EstimateScratchData<dim> &scratch_data,
- const EstimateCopyData<dim> ©_data)
- {
+ GradientEstimation::estimate_cell (const SynchronousIterators<std_cxx1x::tuple<typename DoFHandler<dim>::active_cell_iterator,
+ Vector<float>::iterator> > &cell,
+ EstimateScratchData<dim> &scratch_data,
+ const EstimateCopyData &)
+ {
// We need space for the tensor <code>Y</code>, which is the sum of
// outer products of the y-vectors.
Tensor<2,dim> Y;
GeometryInfo<dim>::max_children_per_face);
typename DoFHandler<dim>::active_cell_iterator cell_it(std_cxx1x::get<0>(cell.iterators));
-
+
// First initialize the <code>FEValues</code> object, as well as the
// <code>Y</code> tensor:
scratch_data.fe_midpoint_value.reinit (cell_it);
// as an internal error. We therefore use a predefined
// exception class to throw here.
Assert (neighbor_child->neighbor(face_no==0 ? 1 : 0)
- ==std_cxx1x::get<0>(cell.iterators),ExcInternalError());
+ ==std_cxx1x::get<0>(cell.iterators),ExcInternalError());
// If the check succeeded, we push the active neighbor
// we just found to the stack we keep:
const Point<dim> neighbor_center = scratch_data.fe_midpoint_value.quadrature_point(0);
scratch_data.fe_midpoint_value.get_function_values (scratch_data.solution,
- neighbor_midpoint_value);
+ neighbor_midpoint_value);
// Compute the vector <code>y</code> connecting the centers of the
// two cells. Note that as opposed to the introduction, we denote
Point<dim> gradient;
contract (gradient, Y_inverse, projected_gradient);
+ // The last part of this function is the one where we
+ // write into the element of the output vector what
+ // we have just computed. As above, we need to get
+ // at the second element of the pair of iterators, which requires
+ // slightly awkward syntax but is not otherwise particularly
+ // difficult:
*(std_cxx1x::get<1>(cell.iterators)) = (std::pow(std_cxx1x::get<0>(cell.iterators)->diameter(),
- 1+1.0*dim/2) *
- std::sqrt(gradient.square()));
-
+ 1+1.0*dim/2) *
+ std::sqrt(gradient.square()));
+
}
}
{
Assert( (dim == spacedim) && (order==1),
ExcMessage("Only allowed for square tensors."));
-
- for (unsigned int j=0; j<dim; ++j)
- (*this)[j] = T[j];
+ if ((dim == spacedim) && (order==1))
+ for (unsigned int j=0; j<dim; ++j)
+ (*this)[j] = T[j];
}
Assert( (dim == spacedim) && (order==1),
ExcMessage("Only allowed for square tensors."));
- for (unsigned int j=0; j<dim; ++j)
- (*this)[j] = ta[j];
+ if ((dim == spacedim) && (order==1))
+ for (unsigned int j=0; j<dim; ++j)
+ (*this)[j] = ta[j];
return *this;
}
Assert( (dim == spacedim) && (order==1),
ExcMessage("Only allowed for square tensors."));
+
+
Tensor<2,dim> t;
- for (unsigned int j=0; j<dim; ++j)
- t[j] = (*this)[j];
+ if ((dim == spacedim) && (order==1))
+ for (unsigned int j=0; j<dim; ++j)
+ t[j] = (*this)[j];
return t;
/**
- Traspose of a rectangular DerivativeForm DF,
+ Transpose of a rectangular DerivativeForm DF,
mostly for compatibility reasons.
@relates DerivativeForm
@author Sebastian Pauletti, 2011
* A pointer to the c_string that will be printed by what(). It is
* populated by generate_message()
*/
- mutable char* what_str;
+ mutable std::string what_str;
};
/**
* This class implements the first family <i>H<sup>curl</sup></i>-conforming,
- * vector-valued polynomials, proposed by J.-C. Nédélec in 1980
+ * vector-valued polynomials, proposed by J.-C. Nédélec in 1980
* (Numer. Math. 35).
*
- * The Nédélec polynomials are constructed such that the curl
+ * The Nédélec polynomials are constructed such that the curl
* is in the tensor product polynomial space <i>Q<sub>k</sub></i>.
* Therefore, the polynomial order of each component must be one
* order higher in the corresponding two directions,
* Q<sub>k+1,k,k+1</sub>, Q<sub>k+1,k+1,k</sub>)</i> in 2D and 3D, resp.
*
* @ingroup Polynomials
- * @author Markus Bürg
+ * @author Markus Bürg
* @date 2009, 2010
*/
template <int dim>
public:
/**
* Constructor. Creates all basis
- * functions for Nédélec polynomials
+ * functions for Nédélec polynomials
* of given degree.
*
* @arg k: the degree of the
- * Nédélec space, which is the degree
+ * Nédélec space, which is the degree
* of the largest tensor product
* polynomial space
* <i>Q<sub>k</sub></i> contained.
/**
* Computes the value and the
* first and second derivatives
- * of each Nédélec
+ * of each Nédélec
* polynomial at @p unit_point.
*
* The size of the vectors must
void compute (const Point<dim> &unit_point, std::vector<Tensor<1, dim> > &values, std::vector<Tensor<2, dim> > &grads, std::vector<Tensor<3, dim> > &grad_grads) const;
/**
- * Returns the number of Nédélec
+ * Returns the number of Nédélec
* polynomials.
*/
unsigned int n () const;
/**
- * Returns the degree of the Nédélec
+ * Returns the degree of the Nédélec
* space, which is one less than
* the highest polynomial degree.
*/
const AnisotropicPolynomials<dim> polynomial_space;
/**
- * Number of Nédélec polynomials.
+ * Number of Nédélec polynomials.
*/
const unsigned int n_pols;
/*@{*/
/**
- * Base class for quadrature formulæ in arbitrary dimensions. This class
+ * Base class for quadrature formulæ in arbitrary dimensions. This class
* stores quadrature points and weights on the unit line [0,1], unit
* square [0,1]x[0,1], etc.
*
* There are a number of derived classes, denoting concrete
- * integration formulæ. Their names names prefixed by
+ * integration formulæ. Their names names prefixed by
* <tt>Q</tt>. Refer to the list of derived classes for more details.
*
* The schemes for higher dimensions are typically tensor products of the
- * one-dimensional formulæ, but refer to the section on implementation
+ * one-dimensional formulæ, but refer to the section on implementation
* detail below.
*
* In order to allow for dimension independent programming, a
* point with weight one. Access to the weight is possible, while
* access to the quadrature point is not permitted, since a Point of
* dimension zero contains no information. The main purpose of these
- * formulæ is their use in QProjector, which will create a useful
+ * formulæ is their use in QProjector, which will create a useful
* formula of dimension one out of them.
*
* <h3>Mathematical background</h3>
* error is <tt>m+1</tt>, that is, the error is the size of the cell
* to the <tt>m+1</tt> by the Bramble-Hilbert Lemma. The number
* <tt>m</tt> is to be found in the documentation of each concrete
- * formula. For the optimal formulæ QGauss we have $m = 2N-1$, where
+ * formula. For the optimal formulæ QGauss we have $m = 2N-1$, where
* N is the constructor parameter to QGauss. The tensor product
- * formulæ are exact on tensor product polynomials of degree
+ * formulæ are exact on tensor product polynomials of degree
* <tt>m</tt> in each space direction, but they are still only of
* <tt>m+1</tt>st order.
*
* <h3>Implementation details</h3>
*
- * Most integration formulæ in more than one space dimension are
- * tensor products of quadrature formulæ in one space dimension, or
+ * Most integration formulæ in more than one space dimension are
+ * tensor products of quadrature formulæ in one space dimension, or
* more generally the tensor product of a formula in <tt>(dim-1)</tt>
* dimensions and one in one dimension. There is a special constructor
* to generate a quadrature formula from two others. For example, the
- * QGauss@<dim@> formulæ include <i>N<sup>dim</sup></i> quadrature
+ * QGauss@<dim@> formulæ include <i>N<sup>dim</sup></i> quadrature
* points in <tt>dim</tt> dimensions, where N is the constructor
* parameter of QGauss.
*
* of the weights of the left- and the rightmost quadrature point.
*
* Since all dimensions higher than one are built up by tensor products of
- * one dimensional and <tt>dim-1</tt> dimensional quadrature formulæ, the
+ * one dimensional and <tt>dim-1</tt> dimensional quadrature formulæ, the
* argument given to the constructor needs to be a quadrature formula in
* one space dimension, rather than in <tt>dim</tt> dimensions.
*
/**
* Milne-rule. Closed Newton-Cotes formula, exact for polynomials of degree 5.
- * See Stoer: Einführung in die Numerische Mathematik I, p. 102
+ * See Stoer: Einführung in die Numerische Mathematik I, p. 102
*/
template <int dim>
class QMilne : public Quadrature<dim>
/**
* Weddle-rule. Closed Newton-Cotes formula, exact for polynomials of degree 7.
- * See Stoer: Einführung in die Numerische Mathematik I, p. 102
+ * See Stoer: Einführung in die Numerische Mathematik I, p. 102
*/
template <int dim>
class QWeddle : public Quadrature<dim>
unsigned int n_tensor_pols;
/**
- * Each tensor product polynomial @þ{i} is a product of one-dimensional
+ * Each tensor product polynomial @þ{i} is a product of one-dimensional
* polynomials in each space direction. Compute the indices of these
* one-dimensional polynomials for each space direction, given the index
* <tt>i</tt>.
*/
const ScratchData *sample_scratch_data;
+ /**
+ * Flag is true if the buffer is used and false if the buffer can be
+ * used.
+ */
+ bool currently_in_use;
+
/**
* Default constructor.
:
n_items (0),
scratch_data (0),
- sample_scratch_data (0)
+ sample_scratch_data (0),
+ currently_in_use (false)
{}
};
:
tbb::filter (/*is_serial=*/true),
remaining_iterator_range (begin, end),
- ring_buffer (buffer_size),
+ item_buffer (buffer_size),
sample_scratch_data (sample_scratch_data),
- n_emitted_items (0),
chunk_size (chunk_size)
{
// initialize the elements of the ring buffer
- for (unsigned int element=0; element<ring_buffer.size(); ++element)
+ for (unsigned int element=0; element<item_buffer.size(); ++element)
{
- Assert (ring_buffer[element].n_items == 0,
+ Assert (item_buffer[element].n_items == 0,
ExcInternalError());
- ring_buffer[element].work_items.resize (chunk_size,
+ item_buffer[element].work_items.resize (chunk_size,
remaining_iterator_range.second);
- ring_buffer[element].scratch_data = &thread_local_scratch;
- ring_buffer[element].sample_scratch_data = &sample_scratch_data;
- ring_buffer[element].copy_datas.resize (chunk_size,
+ item_buffer[element].scratch_data = &thread_local_scratch;
+ item_buffer[element].sample_scratch_data = &sample_scratch_data;
+ item_buffer[element].copy_datas.resize (chunk_size,
sample_copy_data);
+ item_buffer[element].currently_in_use = false;
}
}
*/
virtual void *operator () (void *)
{
- // store the current
- // position of the pointer
- ItemType *current_item
- = &ring_buffer[n_emitted_items % ring_buffer.size()];
+ // find first unused item. we know that there must be one
+ // because we have set the maximal number of tokens in flight
+ // and have set the ring buffer to have exactly this size. so
+ // if this function is called, we know that less than the
+ // maximal number of items in currently in flight
+ ItemType *current_item = 0;
+ for (unsigned int i=0; i<item_buffer.size(); ++i)
+ if (item_buffer[i].currently_in_use == false)
+ {
+ item_buffer[i].currently_in_use = true;
+ current_item = &item_buffer[i];
+ break;
+ }
+ Assert (current_item != 0, ExcMessage ("This can't be. There must be a free item!"));
// initialize the next item. it may
// consist of at most chunk_size
// left. terminate the pipeline
return 0;
else
- {
- ++n_emitted_items;
- return current_item;
- }
+ return current_item;
}
private:
std::pair<Iterator,Iterator> remaining_iterator_range;
/**
- * A ring buffer that will store items.
+ * A buffer that will store items.
*/
- std::vector<ItemType> ring_buffer;
+ std::vector<ItemType> item_buffer;
/**
* Pointer to a thread local variable identifying the scratch data objects
*/
const ScratchData &sample_scratch_data;
- /**
- * Counter for the number of emitted
- * items. Each item may consist of up
- * to chunk_size iterator elements.
- */
- unsigned int n_emitted_items;
-
/**
* Number of elements of the
* iterator range that each
/**
* Initialize the pointers and vector
* elements in the specified entry of
- * the ring buffer.
+ * the item_buffer.
*/
void init_buffer_elements (const unsigned int element,
const CopyData &sample_copy_data)
{
- Assert (ring_buffer[element].n_items == 0,
+ Assert (item_buffer[element].n_items == 0,
ExcInternalError());
- ring_buffer[element].work_items
+ item_buffer[element].work_items
.resize (chunk_size, remaining_iterator_range.second);
- ring_buffer[element].scratch_data
+ item_buffer[element].scratch_data
= &thread_local_scratch;
- ring_buffer[element].sample_scratch_data
+ item_buffer[element].sample_scratch_data
= &sample_scratch_data;
- ring_buffer[element].copy_datas
+ item_buffer[element].copy_datas
.resize (chunk_size, sample_copy_data);
}
};
*/
Worker (const std_cxx1x::function<void (const Iterator &,
ScratchData &,
- CopyData &)> &worker)
+ CopyData &)> &worker,
+ bool copier_exist=true)
:
tbb::filter (/* is_serial= */ false),
- worker (worker)
+ worker (worker),
+ copier_exist (copier_exist)
{}
}
}
+ // if there is no copier, mark current item as usable again
+ if (copier_exist==false)
+ current_item->currently_in_use = false;
// then return the original pointer
const std_cxx1x::function<void (const Iterator &,
ScratchData &,
CopyData &)> worker;
+
+ /**
+ * This flag is true if the copier stage exist. If it does not,
+ * the worker has to free the buffer. Otherwise the copier will do it.
+ */
+ bool copier_exist;
};
}
}
+ // mark current item as useable again
+ current_item->currently_in_use = false;
+
// return an invalid item since we are at the end of the
// pipeline
* and copy data objects this thread will use. The same considerations
* apply as documented in the Implementation2::IteratorRangeToItemStream
* class as well as in the paper by Turcksin, Kronbichler and Bangerth
- * (see @ref workstream_paper).
+ * (see @ref workstream_paper).
*/
Threads::ThreadLocalStorage<ScratchAndCopyDataList> *scratch_and_copy_data;
std::pair<typename std::vector<Iterator>::const_iterator,typename std::vector<Iterator>::const_iterator> remaining_iterator_range;
/**
- * A ring buffer that will store items.
+ * A buffer that will store items.
*/
std::vector<ItemType> item_buffer;
*
* This function that can be used for worker and copier objects that
* are either pointers to non-member functions or objects that allow to be
- * called with an operator(), for example objects created by std::bind.
+ * called with an operator(), for example objects created by std::bind. If
+ * the copier is an empty function, it is ignored in the pipeline.
*
* The argument passed as @p end must be convertible to the same type as @p
* begin, but doesn't have to be of the same type itself. This allows to
sample_scratch_data,
sample_copy_data);
+ // Check that the copier exist
+ if (static_cast<const std_cxx1x::function<void (const CopyData &)>& >(copier))
+ {
+ internal::Implementation2::Worker<Iterator, ScratchData, CopyData> worker_filter (worker);
+ internal::Implementation2::Copier<Iterator, ScratchData, CopyData> copier_filter (copier);
- internal::Implementation2::Worker<Iterator, ScratchData, CopyData> worker_filter (worker);
- internal::Implementation2::Copier<Iterator, ScratchData, CopyData> copier_filter (copier);
+ // now create a pipeline from these stages
+ tbb::pipeline assembly_line;
+ assembly_line.add_filter (iterator_range_to_item_stream);
+ assembly_line.add_filter (worker_filter);
+ assembly_line.add_filter (copier_filter);
- // now create a pipeline from these stages
- tbb::pipeline assembly_line;
- assembly_line.add_filter (iterator_range_to_item_stream);
- assembly_line.add_filter (worker_filter);
- assembly_line.add_filter (copier_filter);
+ // and run it
+ assembly_line.run (queue_length);
- // and run it
- assembly_line.run (queue_length);
+ assembly_line.clear ();
+ }
+ else
+ {
+ internal::Implementation2::Worker<Iterator, ScratchData, CopyData> worker_filter (worker,false);
- assembly_line.clear ();
+ // now create a pipeline from these stages
+ tbb::pipeline assembly_line;
+ assembly_line.add_filter (iterator_range_to_item_stream);
+ assembly_line.add_filter (worker_filter);
+
+ // and run it
+ assembly_line.run (queue_length);
+
+ assembly_line.clear ();
+ }
}
#endif
}
* and Bangerth (see @ref workstream_paper).
*
* This is the function that can be used for worker and copier functions
- * that are member functions of a class.
+ * that are member functions of a class. If the copier is an empty function,
+ * it is ignored in the pipeline.
*
* The argument passed as @p end must be convertible to the same type as @p
* begin, but doesn't have to be of the same type itself. This allows to
ScratchData &,
CopyData &),
void (MainClass::*copier) (const CopyData &),
- const ScratchData &sample_scratch_data,
- const CopyData &sample_copy_data,
- const unsigned int queue_length = 2*multithread_info.n_threads(),
- const unsigned int chunk_size = 8)
+ const ScratchData &sample_scratch_data,
+ const CopyData &sample_copy_data,
+ const unsigned int queue_length = 2*multithread_info.n_threads(),
+ const unsigned int chunk_size = 8)
{
// forward to the other function
run (begin, end,
const Point<DH::space_dimension> &direction,
const bool dof_wise_renumbering = false);
- /**
- * This function does the downstream numbering for the individual levels of
- * a multigrid hierarchy, but not for the global degrees of freedom.
- *
- * @deprecated Call downstream() function that takes a level argument for
- * each of the levels of the multigrid hierarchy.
- */
- template <int dim, int spacedim>
- void
- downstream (MGDoFHandler<dim,spacedim> &dof_handler,
- const Point<spacedim> &direction,
- const bool dof_wise_renumbering = false) DEAL_II_DEPRECATED;
-
/**
* @deprecated Use downstream() instead.
*/
DeclException0 (ExcNotDGFEM);
}
+/* ------------------------- inline functions -------------- */
+
+#ifndef DOXYGEN
+namespace DoFRenumbering
+{
+ template <class DH>
+ void
+ inline
+ downstream (DH &dof,
+ const Point<DH::space_dimension> &direction,
+ const bool dof_wise_renumbering)
+ {
+ std::vector<types::global_dof_index> renumbering(dof.n_dofs());
+ std::vector<types::global_dof_index> reverse(dof.n_dofs());
+ compute_downstream(renumbering, reverse, dof, direction,
+ dof_wise_renumbering);
+
+ dof.renumber_dofs(renumbering);
+ }
+}
+#endif
+
+
DEAL_II_NAMESPACE_CLOSE
#endif
* shape functions created using this constructor correspond to Lagrange
* polynomials in each coordinate direction.
*/
- FE_FaceQ(unsigned int p);
+ FE_FaceQ (const unsigned int p);
virtual FiniteElement<dim,spacedim> *clone() const;
* DGQ_{k}
* @f]
* Consequently, approximation order of
- * the Nedelec space equals the value <i>degree</i> given to the constructor.
+ * the Nédélec space equals the value <i>degree</i> given to the constructor.
* In this scheme, the lowest order element would be created by the call
* FE_Nedelec<dim>(0). Note that this follows the convention of Brezzi and
- * Raviart, though not the one used in the original paper by Nedelec.
+ * Raviart, though not the one used in the original paper by Nédélec.
*
* This class is not implemented for the codimension one case
* (<tt>spacedim != dim</tt>).
* inverse) is needed already to generate the values of the shape
* functions on the cells in real space. This is in contrast to most
* other elements, where you only need the Jacobian for the
- * gradients. Thus, to generate the gradients of Nedelec shape
+ * gradients. Thus, to generate the gradients of Nédélec shape
* functions, one would need to have the derivatives of the inverse of
* the Jacobian matrix.
*
- * Basically, the Nedelec shape functions can be understood as the
+ * Basically, the Nédélec shape functions can be understood as the
* gradients of scalar shape functions on the real cell. They are thus
* the inverse Jacobian matrix times the gradients of scalar shape
- * functions on the unit cell. The gradient of Nedelec shape functions
+ * functions on the unit cell. The gradient of Nédélec shape functions
* is then, by the product rule, the sum of first the derivative (with
* respect to true coordinates) of the inverse Jacobian times the
* gradient (in unit coordinates) of the scalar shape function, plus
* drop this first term.
*
* What this means for the present case: first the computation of
- * gradients of Nedelec shape functions is wrong in general. Second,
+ * gradients of Nédélec shape functions is wrong in general. Second,
* in the following two cases you will not notice this:
*
* - If the cell is a parallelogram, then the usual bi-/trilinear mapping
* and the gradient of the shape functions is computed exactly, since the
* first term is zero.
*
- * - With the Nedelec elements, you will usually want to compute
+ * - With the Nédélec elements, you will usually want to compute
* the curl, not the general derivative tensor. However, the curl of the
* Jacobian vanishes, so for the curl of shape functions the first term
* is irrelevant, and the curl will always be computed correctly even on
* cells onto the father
* cell. According to the
* philosophy of the
- * Nédélec element, this
+ * Nédélec element, this
* restriction operator preserves
* the curl of a function
* weakly.
*
* @ingroup Exceptions
*/
- DeclException0 (ExcAccessToUninitializedField);
+ DeclException1 (ExcAccessToUninitializedField,
+ char *,
+ << ("You are requesting information from an FEValues/FEFaceValues/FESubfaceValues "
+ "object for which this kind of information has not been computed. What "
+ "information these objects compute is determined by the update_* flags you "
+ "pass to the constructor. Here, the operation you are attempting requires "
+ "the <")
+ << arg1
+ << "> flag to be set, but it was apparently not specified upon construction.");
/**
* @todo Document this
*
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
// an adaptation of the FEValuesBase::shape_value_component function
// except that here we know the component as fixed and we have
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
// an adaptation of the
// FEValuesBase::shape_grad_component
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
// an adaptation of the
// FEValuesBase::shape_grad_component
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
// same as for the scalar case except
// that we have one more index
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
// same as for the scalar case except
// that we have one more index
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
// same as for the scalar case except
// that we have one more index
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
// same as for the scalar case except that we have one more index
const int snc = shape_function_data[shape_function].single_nonzero_component;
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
// same as for the scalar case except
// that we have one more index
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
// same as for the scalar case except
// that we have one more index
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
// similar to the vector case where we
// have more then one index and we need
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
const int snc = shape_function_data[shape_function].single_nonzero_component;
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
// similar to the vector case where we
// have more then one index and we need
Assert (shape_function < fe_values.fe->dofs_per_cell,
ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell));
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
const int snc = shape_function_data[shape_function].single_nonzero_component;
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_values,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_values"));
Assert (fe->is_primitive (i),
ExcShapeFunctionNotPrimitive(i));
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_values,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_values"));
Assert (component < fe->n_components(),
ExcIndexRange(component, 0, fe->n_components()));
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_gradients,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_gradients"));
Assert (fe->is_primitive (i),
ExcShapeFunctionNotPrimitive(i));
Assert (i<this->shape_gradients.size(),
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_gradients,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_gradients"));
Assert (component < fe->n_components(),
ExcIndexRange(component, 0, fe->n_components()));
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_hessians,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_hessians"));
Assert (fe->is_primitive (i),
ExcShapeFunctionNotPrimitive(i));
Assert (i<this->shape_hessians.size(),
Assert (i < fe->dofs_per_cell,
ExcIndexRange (i, 0, fe->dofs_per_cell));
Assert (this->update_flags & update_hessians,
- ExcAccessToUninitializedField());
+ ExcAccessToUninitializedField("update_hessians"));
Assert (component < fe->n_components(),
ExcIndexRange(component, 0, fe->n_components()));
const std::vector<Point<spacedim> > &
FEValuesBase<dim,spacedim>::get_quadrature_points () const
{
- Assert (this->update_flags & update_quadrature_points, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_quadrature_points,
+ ExcAccessToUninitializedField("update_quadrature_points"));
return this->quadrature_points;
}
const std::vector<double> &
FEValuesBase<dim,spacedim>::get_JxW_values () const
{
- Assert (this->update_flags & update_JxW_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_JxW_values,
+ ExcAccessToUninitializedField("update_JxW_values"));
return this->JxW_values;
}
const std::vector<DerivativeForm<1,dim,spacedim> > &
FEValuesBase<dim,spacedim>::get_jacobians () const
{
- Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_jacobians,
+ ExcAccessToUninitializedField("update_jacobians"));
return this->jacobians;
}
const std::vector<DerivativeForm<2,dim,spacedim> > &
FEValuesBase<dim,spacedim>::get_jacobian_grads () const
{
- Assert (this->update_flags & update_jacobian_grads, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_jacobian_grads,
+ ExcAccessToUninitializedField("update_jacobians_grads"));
return this->jacobian_grads;
}
const std::vector<DerivativeForm<1,spacedim,dim> > &
FEValuesBase<dim,spacedim>::get_inverse_jacobians () const
{
- Assert (this->update_flags & update_inverse_jacobians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_inverse_jacobians,
+ ExcAccessToUninitializedField("update_inverse_jacobians"));
return this->inverse_jacobians;
}
const Point<spacedim> &
FEValuesBase<dim,spacedim>::quadrature_point (const unsigned int i) const
{
- Assert (this->update_flags & update_quadrature_points, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_quadrature_points,
+ ExcAccessToUninitializedField("update_quadrature_points"));
Assert (i<this->quadrature_points.size(), ExcIndexRange(i, 0, this->quadrature_points.size()));
return this->quadrature_points[i];
double
FEValuesBase<dim,spacedim>::JxW (const unsigned int i) const
{
- Assert (this->update_flags & update_JxW_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_JxW_values,
+ ExcAccessToUninitializedField("update_JxW_values"));
Assert (i<this->JxW_values.size(), ExcIndexRange(i, 0, this->JxW_values.size()));
return this->JxW_values[i];
const DerivativeForm<1,dim,spacedim> &
FEValuesBase<dim,spacedim>::jacobian (const unsigned int i) const
{
- Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_jacobians,
+ ExcAccessToUninitializedField("update_jacobians"));
Assert (i<this->jacobians.size(), ExcIndexRange(i, 0, this->jacobians.size()));
return this->jacobians[i];
const DerivativeForm<2,dim,spacedim> &
FEValuesBase<dim,spacedim>::jacobian_grad (const unsigned int i) const
{
- Assert (this->update_flags & update_jacobian_grads, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_jacobian_grads,
+ ExcAccessToUninitializedField("update_jacobians_grads"));
Assert (i<this->jacobian_grads.size(), ExcIndexRange(i, 0, this->jacobian_grads.size()));
return this->jacobian_grads[i];
const DerivativeForm<1,spacedim,dim> &
FEValuesBase<dim,spacedim>::inverse_jacobian (const unsigned int i) const
{
- Assert (this->update_flags & update_inverse_jacobians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_inverse_jacobians,
+ ExcAccessToUninitializedField("update_inverse_jacobians"));
Assert (i<this->inverse_jacobians.size(), ExcIndexRange(i, 0, this->inverse_jacobians.size()));
return this->inverse_jacobians[i];
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (this->update_flags & update_normal_vectors,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_normal_vectors"));
Assert (i<this->normal_vectors.size(),
ExcIndexRange(i, 0, this->normal_vectors.size()));
Assert (i<this->boundary_forms.size(),
ExcIndexRange(i, 0, this->boundary_forms.size()));
Assert (this->update_flags & update_boundary_forms,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_boundary_forms"));
return this->boundary_forms[i];
}
* valued version, namely on the face <i>F</i>
* the vector
* @f[
- * \int_F \Bigl(\gamma (u-g) v - \partial_n u v - (u-g) \partial_n v\Bigr)\;ds.
+ * \int_F \Bigl(\gamma (\mathbf u- \mathbf g) \cdot \mathbf v
+ - \partial_n \mathbf u \cdot \mathbf v
+ - (\mathbf u-\mathbf g) \cdot \partial_n \mathbf v\Bigr)\;ds.
* @f]
*
* Here, <i>u</i> is the finite element function whose values and
}
}
+ /**
+ * Flux for the interior penalty method for the Laplacian applied
+ * to the tangential components of a vector field, namely on
+ * the face <i>F</i> the matrices associated with the bilinear form
+ * @f[
+ * \int_F \Bigl( \gamma [u_\tau][v_\tau] - \{\nabla u_\tau\}[v_\tau\mathbf n] - [u_\tau\mathbf
+ * n]\{\nabla v_\tau\} \Bigr) \; ds.
+ * @f]
+ *
+ * @warning This function is still under development!
+ *
+ * @author Bärbel Janssen, Guido Kanschat
+ * @date 2013
+ */
template <int dim>
void ip_tangential_matrix (
FullMatrix<double> &M11,
}
/**
- * Residual term for the symmetric interior penalty method.
+ * Residual term for the symmetric interior penalty method:
+ * @f[
+ * \int_F \Bigl( \gamma [u][v] - \{\nabla u\}[v\mathbf n] - [u\mathbf
+ * n]\{\nabla v\} \Bigr) \; ds.
+ * @f]
*
* @author Guido Kanschat
* @date 2012
/**
- * Vector-valued residual term for the symmetric interior penalty method.
+ * Vector-valued residual term for the symmetric interior penalty method:
+ * @f[
+ * \int_F \Bigl( \gamma [\mathbf u]\cdot[\mathbf v]
+ - \{\nabla \mathbf u\}[\mathbf v\otimes \mathbf n]
+ - [\mathbf u\otimes \mathbf n]\{\nabla \mathbf v\} \Bigr) \; ds.
+ * @f]
*
* @author Guido Kanschat
* @date 2012
*/
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.
+ */
+ void resolve_indices(std::vector<types::global_dof_index> &indices) const;
+
/**
* @}
*/
#endif // DEAL_II_WITH_MUMPS
double *a;
- double *rhs;
+ std::vector<double> rhs;
int *irn;
int *jcn;
types::global_dof_index n;
*/
void copy_solution (Vector<double> &vector);
+ /**
+ *
+ */
+ void copy_rhs_to_mumps(const Vector<double> &rhs);
+
/**
* Flags storing whether the function <tt>initialize ()</tt> has already
* been called.
/**
* A function in which the linear system is solved and the solution
- * vector is copied into the given <tt>vector</tt>.
+ * vector is copied into the given <tt>vector</tt>. The right-hand side
+ * need to be supplied in initialize(matrix, vector);
*/
void solve (Vector<double> &vector);
::apply_values (const VectorizedArray<Number> in [],
VectorizedArray<Number> out [])
{
- internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
+ // for linear elements, the even-odd decomposition is slower than the plain
+ // evaluation (additions to create the symmetric and anti-symmetric part),
+ // for all other orders, we choose even-odd
+ if (fe_degree > 1 || n_q_points_1d > 3)
+ internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
VectorizedArray<Number>, direction, dof_to_quad, add, 0>
(shape_val_evenodd, in, out);
+ else
+ internal::apply_tensor_product_values<dim,fe_degree,n_q_points_1d,
+ VectorizedArray<Number>, direction, dof_to_quad, add>
+ (this->data.shape_values.begin(), in, out);
}
::apply_gradients (const VectorizedArray<Number> in [],
VectorizedArray<Number> out [])
{
- internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
+ if (fe_degree > 1 || n_q_points_1d > 3)
+ internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
VectorizedArray<Number>, direction, dof_to_quad, add, 1>
(shape_gra_evenodd, in, out);
+ else
+ internal::apply_tensor_product_gradients<dim,fe_degree,n_q_points_1d,
+ VectorizedArray<Number>, direction, dof_to_quad, add>
+ (this->data.shape_gradients.begin(), in, out);
}
::apply_hessians (const VectorizedArray<Number> in [],
VectorizedArray<Number> out [])
{
- internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
+ if (fe_degree > 1 || n_q_points_1d > 3)
+ internal::apply_tensor_product_evenodd<dim,fe_degree,n_q_points_1d,
VectorizedArray<Number>, direction, dof_to_quad, add, 2>
(shape_hes_evenodd, in, out);
+ else
+ internal::apply_tensor_product_hessians<dim,fe_degree,n_q_points_1d,
+ VectorizedArray<Number>, direction, dof_to_quad, add>
+ (this->data.shape_hessians.begin(), in, out);
}
// initialize the basic multithreading information that needs to be
// passed to the DoFInfo structure
#ifdef DEAL_II_WITH_THREADS
- if (additional_data.tasks_parallel_scheme != AdditionalData::none)
+ if (additional_data.tasks_parallel_scheme != AdditionalData::none &&
+ multithread_info.n_threads() > 1)
{
task_info.use_multithreading = true;
task_info.block_size = additional_data.tasks_block_size;
// initialize the basic multithreading information that needs to be
// passed to the DoFInfo structure
#ifdef DEAL_II_WITH_THREADS
- if (additional_data.tasks_parallel_scheme != AdditionalData::none)
+ if (additional_data.tasks_parallel_scheme != AdditionalData::none &&
+ multithread_info.n_threads() > 1)
{
task_info.use_multithreading = true;
task_info.block_size = additional_data.tasks_block_size;
* replaced by a hp::MappingCollection in
* case of a hp::DoFHandler.
*/
- template <class VECTOR, class DH>
- void interpolate (const Mapping<DH::dimension,DH::space_dimension> &mapping,
- const DH &dof,
- const Function<DH::space_dimension> &function,
- VECTOR &vec);
+ template <class VECTOR, int dim, int spacedim, template <int,int> class DH>
+ void interpolate (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof,
+ const Function<spacedim> &function,
+ VECTOR &vec);
/**
* Calls the @p interpolate()
namespace VectorTools
{
- template <class VECTOR, class DH>
- void interpolate (const Mapping<DH::dimension,DH::space_dimension> &mapping,
- const DH &dof,
- const Function<DH::space_dimension> &function,
- VECTOR &vec)
+ template <class VECTOR, int dim, int spacedim, template <int,int> class DH>
+ void interpolate (const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof,
+ const Function<spacedim> &function,
+ VECTOR &vec)
{
- const unsigned int dim=DH::dimension;
-
Assert (dof.get_fe().n_components() == function.n_components,
ExcDimensionMismatch(dof.get_fe().n_components(),
function.n_components));
- const hp::FECollection<DH::dimension,DH::space_dimension> fe (dof.get_fe());
+ const hp::FECollection<dim,spacedim> fe (dof.get_fe());
const unsigned int n_components = fe.n_components();
const bool fe_is_system = (n_components != 1);
- typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ typename DH<dim,spacedim>::active_cell_iterator cell = dof.begin_active(),
+ endc = dof.end();
// For FESystems many of the
// unit_support_points will appear
const unsigned int max_rep_points = *std::max_element (n_rep_points.begin(),
n_rep_points.end());
std::vector<types::global_dof_index> dofs_on_cell (fe.max_dofs_per_cell());
- std::vector<Point<DH::space_dimension> > rep_points (max_rep_points);
+ std::vector<Point<spacedim> > rep_points (max_rep_points);
// get space for the values of the
// function at the rep support points.
// Transformed support points are computed by
// FEValues
- hp::MappingCollection<dim,DH::space_dimension> mapping_collection (mapping);
+ hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
- hp::FEValues<dim, DH::space_dimension> fe_values (mapping_collection,
+ hp::FEValues<dim,spacedim> fe_values (mapping_collection,
fe, support_quadrature, update_quadrature_points);
for (; cell!=endc; ++cell)
// get location of finite element
// support_points
fe_values.reinit(cell);
- const std::vector<Point<DH::space_dimension> > &support_points =
+ const std::vector<Point<spacedim> > &support_points =
fe_values.get_present_fe_values().get_quadrature_points();
// pick out the representative
case H1_norm:
exponent = 2.;
break;
-
+
case L1_norm:
exponent = 1.;
break;
-
+
default:
break;
}
if (spacedim == dim+1)
update_flags |= UpdateFlags (update_normal_vectors);
// no break!
-
+
default:
update_flags |= UpdateFlags (update_values);
break;
while (n_th_vector < vector_data_ranges.size() && std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) < data_set) n_th_vector++;
// Determine the dimension of this data
- if (std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) == data_set)
+ if (n_th_vector < vector_data_ranges.size() && std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) == data_set)
{
// Multiple dimensions
pt_data_vector_dim = std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) - std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1;
function(""),
cond(""),
exc(""),
- stacktrace (0),
+ stacktrace (NULL),
n_stacktrace_frames (0),
- what_str(0)
+ what_str("")
{}
function(exc.function),
cond(exc.cond),
exc(exc.exc),
- stacktrace (0), // don't copy stacktrace to avoid double de-allocation problem
+ stacktrace (NULL), // don't copy stacktrace to avoid double de-allocation problem
n_stacktrace_frames (0),
- what_str(0) // don't copy the error message, it gets generated dynamically by what()
+ what_str("") // don't copy the error message, it gets generated dynamically by what()
{}
ExceptionBase::~ExceptionBase () throw ()
{
- if (stacktrace != 0)
- {
- free (stacktrace);
- stacktrace = 0;
- }
- if (what_str != 0)
- {
- delete[] what_str;
- what_str = 0;
- }
+ free (stacktrace); // free(NULL) is allowed
+ stacktrace = NULL;
}
exc = e;
// If the system supports this, get a stacktrace how we got here:
- if (stacktrace != 0)
- {
- free (stacktrace);
- stacktrace = 0;
- }
-
// Note that we defer the symbol lookup done by backtrace_symbols()
// to when we need it (see what() below). This is for performance
// reasons, as this requires loading libraries and can take in the
const char* ExceptionBase::what() const throw()
{
// If no error c_string was generated so far, do it now:
- if (what_str == 0)
+ if (what_str == "")
{
#ifdef HAVE_GLIBC_STACKTRACE
// We have deferred the symbol lookup to this point to avoid costly
// runtime penalties due to linkage of external libraries by
// backtrace_symbols.
+
+ // first delete old stacktrace if necessary
+ free (stacktrace); // free(NULL) is allowed
stacktrace = backtrace_symbols(raw_stacktrace, n_stacktrace_frames);
#endif
generate_message();
}
- return what_str;
+ return what_str.c_str();
}
converter << "--------------------------------------------------------"
<< std::endl;
- if (what_str != 0)
- delete[] what_str;
- what_str = new char[converter.str().size()+1]; // beware of the terminating \0 character
- strcpy(what_str, converter.str().c_str());
+ what_str = converter.str();
}
catch (...)
{
// On error, resume next. There is nothing better we can do...
+ what_str = "ExceptionBase::generate_message () failed";
}
}
- template <class DH>
- void
- downstream (DH &dof,
- const Point<DH::space_dimension> &direction,
- const bool dof_wise_renumbering)
- {
- std::vector<types::global_dof_index> renumbering(dof.n_dofs());
- std::vector<types::global_dof_index> reverse(dof.n_dofs());
- compute_downstream(renumbering, reverse, dof, direction,
- dof_wise_renumbering);
-
- dof.renumber_dofs(renumbering);
- }
- template <int dim, int spacedim>
- void
- downstream (MGDoFHandler<dim,spacedim> &dof_handler,
- const Point<spacedim> &direction,
- const bool dof_wise_renumbering)
- {
- for (unsigned int level=0; level<dof_handler.n_levels(); ++level)
- downstream(dof_handler, level, direction, dof_wise_renumbering);
- }
template <class DH>
const DoFHandler<deal_II_dimension>&, unsigned int,
const std::vector<DoFHandler<deal_II_dimension>::level_cell_iterator>&);
- template void
- downstream<DoFHandler<deal_II_dimension> >
- (DoFHandler<deal_II_dimension>&, const Point<DoFHandler<deal_II_dimension>::space_dimension>&,
- const bool);
-
template void
compute_downstream<DoFHandler<deal_II_dimension> >
(std::vector<types::global_dof_index>&,std::vector<types::global_dof_index>&,
const hp::DoFHandler<deal_II_dimension>&,
const std::vector<hp::DoFHandler<deal_II_dimension>::active_cell_iterator>&);
- template void
- downstream<hp::DoFHandler<deal_II_dimension> >
- (hp::DoFHandler<deal_II_dimension>&,
- const Point<hp::DoFHandler<deal_II_dimension>::space_dimension>&,
- const bool);
-
- template void
- downstream<MGDoFHandler<deal_II_dimension> >
- (MGDoFHandler<deal_II_dimension>&,
- const Point<MGDoFHandler<deal_II_dimension>::space_dimension>&,
- const bool);
-
template void
downstream<MGDoFHandler<deal_II_dimension> >
(MGDoFHandler<deal_II_dimension>&,
n_dofs_on_children = fe.dofs_per_vertex + 2*fe.dofs_per_line;
dofs_on_mother.resize (n_dofs_on_mother);
- dofs_on_children.resize (n_dofs_on_children);
+ // we might not use all of those in case of artificial cells,
+ // so do not resize(), but reserve() and use push_back later.
+ dofs_on_children.clear();
+ dofs_on_children.reserve (n_dofs_on_children);
Assert(n_dofs_on_mother == fe.constraints().n(),
ExcDimensionMismatch(n_dofs_on_mother,
dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
AssertDimension (next_index, dofs_on_mother.size());
- next_index = 0;
for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->vertex_dof_index(1,dof,fe_index);
+ dofs_on_children.push_back(
+ this_face->child(0)->vertex_dof_index(1,dof,fe_index));
for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(child)->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_children.size());
+ {
+ // skip artificial cells
+ if (cell->neighbor_child_on_subface (face, child)->is_artificial())
+ continue;
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_children.push_back(
+ this_face->child(child)->dof_index(dof, fe_index));
+ }
+ // note: can get fewer DoFs when we have artificial cells
+ Assert(dofs_on_children.size() <= n_dofs_on_children, ExcInternalError());
// for each row in the constraint matrix for this line:
for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
//TODO[TL]: think about this and the following in case of anisotropic refinement
dofs_on_mother.resize (n_dofs_on_mother);
- dofs_on_children.resize (n_dofs_on_children);
+ // we might not use all of those in case of artificial cells,
+ // so do not resize(), but reserve() and use push_back later.
+ dofs_on_children.clear();
+ dofs_on_children.reserve (n_dofs_on_children);
Assert(n_dofs_on_mother == fe.constraints().n(),
ExcDimensionMismatch(n_dofs_on_mother,
dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
AssertDimension (next_index, dofs_on_mother.size());
- next_index = 0;
-
- // assert some consistency assumptions
+ //TODO: assert some consistency assumptions
//TODO[TL]: think about this in case of anisotropic
//refinement
(this_face->child(0)->vertex_index(3) ==
this_face->child(3)->vertex_index(0))),
ExcInternalError());
+
for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->vertex_dof_index(3,dof);
+ dofs_on_children.push_back(
+ this_face->child(0)->vertex_dof_index(3,dof));
// dof numbers on the centers of the lines bounding this
// face
for (unsigned int line=0; line<4; ++line)
for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index);
+ dofs_on_children.push_back(
+ this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index));
// next the dofs on the lines interior to the face; the
// order of these lines is laid down in the FiniteElement
// class documentation
for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->line(1)->dof_index(dof, fe_index);
+ dofs_on_children.push_back(
+ this_face->child(0)->line(1)->dof_index(dof, fe_index));
for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(2)->line(1)->dof_index(dof, fe_index);
+ dofs_on_children.push_back(
+ this_face->child(2)->line(1)->dof_index(dof, fe_index));
for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->line(3)->dof_index(dof, fe_index);
+ dofs_on_children.push_back(
+ this_face->child(0)->line(3)->dof_index(dof, fe_index));
for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(1)->line(3)->dof_index(dof, fe_index);
+ dofs_on_children.push_back(
+ this_face->child(1)->line(3)->dof_index(dof, fe_index));
// dofs on the bordering lines
for (unsigned int line=0; line<4; ++line)
for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->line(line)->child(child)->dof_index(dof, fe_index);
+ {
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_children.push_back(
+ this_face->line(line)->child(child)->dof_index(dof, fe_index));
+ }
// finally, for the dofs interior to the four child faces
for (unsigned int child=0; child<4; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(child)->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_children.size());
+ {
+ // skip artificial cells
+ if (cell->neighbor_child_on_subface (face, child)->is_artificial())
+ continue;
+ for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+ dofs_on_children.push_back(
+ this_face->child(child)->dof_index(dof, fe_index));
+ }
+
+ // note: can get fewer DoFs when we have artificial cells:
+ Assert(dofs_on_children.size() <= n_dofs_on_children, ExcInternalError());
// for each row in the constraint matrix for this line:
for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
}
-
+
template<typename DH>
void
make_periodicity_constraints (const DH &dof_handler,
{
namespace Assembler
{
- struct Scratch
- {
- Scratch() {};
- };
+ struct Scratch {};
template <int dim,int spacedim>
struct CopyData
{
- CopyData(unsigned int const &coarse_component,
- std::vector<types::global_dof_index> const &weight_mapping);
-
- CopyData(CopyData const &data);
-
- unsigned int coarse_component;
- unsigned int dofs_per_cell;
+ unsigned int dofs_per_cell;
std::vector<types::global_dof_index> parameter_dof_indices;
- std::vector<types::global_dof_index> weight_mapping;
std::vector<dealii::Vector<double> > global_parameter_representation;
};
-
-
-
- template <int dim,int spacedim>
- CopyData<dim,spacedim>::CopyData(unsigned int const &coarse_component,
- std::vector<types::global_dof_index> const &weight_mapping) :
- coarse_component(coarse_component),
- weight_mapping(weight_mapping)
- {}
-
-
-
- template <int dim,int spacedim>
- CopyData<dim,spacedim>::CopyData(CopyData const &data) :
- coarse_component(data.coarse_component),
- dofs_per_cell(data.dofs_per_cell),
- parameter_dof_indices(data.parameter_dof_indices),
- weight_mapping(data.weight_mapping),
- global_parameter_representation(data.global_parameter_representation)
- {}
}
namespace
{
/**
* This is a function that is called by the _2 function and that
- * operates on one cell only. It is worked in parallel if
+ * operates on one cell only. It is worked in parallel if
* multhithreading is available.
*/
template <int dim, int spacedim>
void compute_intergrid_weights_3 (
- typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator const &cell,
- Assembler::Scratch const &scratch,
+ const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &cell,
+ const Assembler::Scratch &,
Assembler::CopyData<dim,spacedim> ©_data,
- FiniteElement<dim,spacedim> const &coarse_fe,
- InterGridMap<dealii::DoFHandler<dim,spacedim> > const &coarse_to_fine_grid_map,
- std::vector<dealii::Vector<double> > const ¶meter_dofs)
-
+ const unsigned int coarse_component,
+ const FiniteElement<dim,spacedim> &coarse_fe,
+ const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+ const std::vector<dealii::Vector<double> > ¶meter_dofs,
+ const std::vector<types::global_dof_index> &weight_mapping)
{
// for each cell on the parameter grid: find out which degrees of
// freedom on the fine grid correspond in which way to the degrees
// vector to hold the representation of a single degree of freedom
// on the coarse grid (for the selected fe) on the fine grid
- const types::global_dof_index n_fine_dofs = copy_data.weight_mapping.size();
+ const types::global_dof_index n_fine_dofs = weight_mapping.size();
copy_data.dofs_per_cell = coarse_fe.dofs_per_cell;
copy_data.parameter_dof_indices.resize(copy_data.dofs_per_cell);
-
// get the global indices of the parameter dofs on this
// parameter grid cell
cell->get_dof_indices (copy_data.parameter_dof_indices);
+ // reset the output array to a pristine state
+ copy_data.global_parameter_representation.clear ();
+
// loop over all dofs on this cell and check whether they are
// interesting for us
for (unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
if (coarse_fe.system_to_component_index(local_dof).first
==
- copy_data.coarse_component)
+ coarse_component)
{
// the how-many-th parameter is this on this cell?
const unsigned int local_parameter_dof
/**
* This is a function that is called by the _2 function and that
- * operates on one cell only. It is worked in parallel if
+ * operates on one cell only. It is worked in parallel if
* multhithreading is available.
*/
template <int dim,int spacedim>
- void copy_intergrid_weights_3(Assembler::CopyData<dim,spacedim> const ©_data,
- FiniteElement<dim,spacedim> const &coarse_fe,
+ void copy_intergrid_weights_3(const Assembler::CopyData<dim,spacedim> ©_data,
+ const unsigned int coarse_component,
+ const FiniteElement<dim,spacedim> &coarse_fe,
+ const std::vector<types::global_dof_index> &weight_mapping,
std::vector<std::map<types::global_dof_index, float> > &weights)
{
- unsigned int pos(0);
+ unsigned int pos = 0;
for (unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
if (coarse_fe.system_to_component_index(local_dof).first
==
- copy_data.coarse_component)
+ coarse_component)
{
// now that we've got the global representation of each
// parameter dof, we've only got to clobber the non-zero
// since it should happen rather rarely that there are
// several threads operating on different intergrid
// weights, have only one mutex for all of them
- for (types::global_dof_index i=0; i<copy_data.global_parameter_representation[pos].size();
+ for (types::global_dof_index i=0; i<copy_data.global_parameter_representation[pos].size();
++i)
// set this weight if it belongs to a parameter dof.
- if (copy_data.weight_mapping[i] != numbers::invalid_dof_index)
+ if (weight_mapping[i] != numbers::invalid_dof_index)
{
// only overwrite old value if not by zero
if (copy_data.global_parameter_representation[pos](i) != 0)
{
const types::global_dof_index wi = copy_data.parameter_dof_indices[local_dof],
- wj = copy_data.weight_mapping[i];
+ wj = weight_mapping[i];
weights[wi][wj] = copy_data.global_parameter_representation[pos](i);
- };
+ }
}
else
Assert (copy_data.global_parameter_representation[pos](i) == 0,
ExcInternalError());
++pos;
}
-
+
}
/**
* This is a helper function that is used in the computation of
- * integrid constraints. See the function for a thorough description
+ * intergrid constraints. See the function for a thorough description
* of how it works.
*/
template <int dim, int spacedim>
std::vector<std::map<types::global_dof_index,float> > &weights)
{
Assembler::Scratch scratch;
- Assembler::CopyData<dim,spacedim> copy_data(coarse_component,weight_mapping);
-
- WorkStream::run(coarse_grid.begin_active(),coarse_grid.end(),
- static_cast<std_cxx1x::function<void (typename dealii::DoFHandler<dim,spacedim>
- ::active_cell_iterator const &,Assembler::Scratch const &,Assembler::CopyData<dim,spacedim>
- &)> > (
- std_cxx1x::bind(&compute_intergrid_weights_3<dim,spacedim>,
- std_cxx1x::_1,
- std_cxx1x::_2,
- std_cxx1x::_3,
- std_cxx1x::cref(coarse_grid.get_fe()),
- std_cxx1x::cref(coarse_to_fine_grid_map),
- std_cxx1x::cref(parameter_dofs))),
- static_cast<std_cxx1x::function<void (Assembler
- ::CopyData<dim,spacedim> const &)> > (
- std_cxx1x::bind(©_intergrid_weights_3<dim,spacedim>,
- std_cxx1x::_1,
- std_cxx1x::cref(coarse_grid.get_fe()),
- std_cxx1x::ref(weights))),
+ Assembler::CopyData<dim,spacedim> copy_data;
+
+ WorkStream::run(coarse_grid.begin_active(),
+ coarse_grid.end(),
+ std_cxx1x::bind(&compute_intergrid_weights_3<dim,spacedim>,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3,
+ coarse_component,
+ std_cxx1x::cref(coarse_grid.get_fe()),
+ std_cxx1x::cref(coarse_to_fine_grid_map),
+ std_cxx1x::cref(parameter_dofs),
+ std_cxx1x::cref(weight_mapping)),
+ std_cxx1x::bind(©_intergrid_weights_3<dim,spacedim>,
+ std_cxx1x::_1,
+ coarse_component,
+ std_cxx1x::cref(coarse_grid.get_fe()),
+ std_cxx1x::cref(weight_mapping),
+ std_cxx1x::ref(weights)),
scratch,
copy_data);
}
cell->at_boundary ())
{
const FiniteElement<dim,spacedim> &fe = cell->get_fe();
-
+
// get global indices of dofs on the cell
cell_dofs.resize (fe.dofs_per_cell);
cell->get_dof_indices (cell_dofs);
-
+
for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
++face_no)
{
const typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
-
+
// if face is on the boundary and satisfies the correct
// boundary id property
if (face->at_boundary ()
{
// Find out if a dof has a contribution in this
// component, and if so, add it to the list
- const std::vector<types::global_dof_index>::iterator it_index_on_cell
+ const std::vector<types::global_dof_index>::iterator it_index_on_cell
= std::find (cell_dofs.begin(), cell_dofs.end(), face_dofs[i]);
Assert (it_index_on_cell != cell_dofs.end(), ExcInvalidIterator());
const unsigned int index_on_cell = std::distance(cell_dofs.begin(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert (fe_values.present_cell.get () != 0,
ExcMessage ("FEValues object is not reinited to any cell"));
AssertDimension (fe_function.size (),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
Assert (fe_values.present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(),
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_hessians"));
Assert (laplacians.size() == fe_values.n_quadrature_points,
ExcDimensionMismatch(laplacians.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
{
typedef FEValuesBase<dim, spacedim> FVB;
Assert(fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
Assert(fe_values.present_cell.get() != 0,
ExcMessage("FEValues object is not reinit'ed to any cell"));
AssertDimension(fe_function.size(),
{
typedef FEValuesBase<dim, spacedim> FVB;
Assert(fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert(fe_values.present_cell.get() != 0,
ExcMessage("FEValues object is not reinit'ed to any cell"));
AssertDimension(fe_function.size(),
{
typedef FEValuesBase<dim, spacedim> FVB;
Assert(fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_values"));
Assert(fe_values.present_cell.get() != 0,
ExcMessage("FEValues object is not reinit'ed to any cell"));
AssertDimension(fe_function.size(),
{
typedef FEValuesBase<dim, spacedim> FVB;
Assert(fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField("update_gradients"));
Assert(fe_values.present_cell.get() != 0,
ExcMessage("FEValues object is not reinit'ed to any cell"));
AssertDimension(fe_function.size(),
const InputVector &fe_function,
std::vector<number> &values) const
{
- Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_values,
+ ExcAccessToUninitializedField("update_values"));
AssertDimension (fe->n_components(), 1);
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
const VectorSlice<const std::vector<types::global_dof_index> > &indices,
std::vector<number> &values) const
{
- Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_values,
+ ExcAccessToUninitializedField("update_values"));
AssertDimension (fe->n_components(), 1);
AssertDimension (indices.size(), dofs_per_cell);
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
- Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_values,
+ ExcAccessToUninitializedField("update_values"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
// get function values of dofs on this cell
// number of function values is generated in each point.
Assert (indices.size() % dofs_per_cell == 0,
ExcNotMultiple(indices.size(), dofs_per_cell));
- Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_values,
+ ExcAccessToUninitializedField("update_values"));
VectorSlice<std::vector<Vector<number> > > val(values);
if (indices.size() <= 100)
VectorSlice<std::vector<std::vector<double> > > values,
bool quadrature_points_fastest) const
{
- Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_values,
+ ExcAccessToUninitializedField("update_values"));
// Size of indices must be a multiple of dofs_per_cell such that an integer
// number of function values is generated in each point.
const InputVector &fe_function,
std::vector<Tensor<1,spacedim> > &gradients) const
{
- Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_gradients,
+ ExcAccessToUninitializedField("update_gradients"));
AssertDimension (fe->n_components(), 1);
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
const VectorSlice<const std::vector<types::global_dof_index> > &indices,
std::vector<Tensor<1,spacedim> > &gradients) const
{
- Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_gradients,
+ ExcAccessToUninitializedField("update_gradients"));
AssertDimension (fe->n_components(), 1);
AssertDimension (indices.size(), dofs_per_cell);
if (dofs_per_cell <= 100)
const InputVector &fe_function,
std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const
{
- Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_gradients,
+ ExcAccessToUninitializedField("update_gradients"));
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
// number of function values is generated in each point.
Assert (indices.size() % dofs_per_cell == 0,
ExcNotMultiple(indices.size(), dofs_per_cell));
- Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_gradients,
+ ExcAccessToUninitializedField("update_gradients"));
+
if (indices.size() <= 100)
{
double dof_values[100];
std::vector<Tensor<2,spacedim> > &hessians) const
{
AssertDimension (fe->n_components(), 1);
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
const VectorSlice<const std::vector<types::global_dof_index> > &indices,
std::vector<Tensor<2,spacedim> > &hessians) const
{
- Assert (this->update_flags & update_second_derivatives,
- ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
AssertDimension (indices.size(), dofs_per_cell);
if (dofs_per_cell <= 100)
std::vector<std::vector<Tensor<2,spacedim> > > &hessians,
bool quadrature_points_fastest) const
{
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
VectorSlice<std::vector<std::vector<Tensor<2,spacedim> > > > hessians,
bool quadrature_points_fastest) const
{
- Assert (this->update_flags & update_second_derivatives,
- ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
Assert (indices.size() % dofs_per_cell == 0,
ExcNotMultiple(indices.size(), dofs_per_cell));
if (indices.size() <= 100)
const InputVector &fe_function,
std::vector<number> &laplacians) const
{
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
AssertDimension (fe->n_components(), 1);
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
const VectorSlice<const std::vector<types::global_dof_index> > &indices,
std::vector<number> &laplacians) const
{
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
AssertDimension (fe->n_components(), 1);
AssertDimension (indices.size(), dofs_per_cell);
if (dofs_per_cell <= 100)
{
Assert (present_cell.get() != 0,
ExcMessage ("FEValues object is not reinit'ed to any cell"));
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
// get function values of dofs on this cell
// number of function values is generated in each point.
Assert (indices.size() % dofs_per_cell == 0,
ExcNotMultiple(indices.size(), dofs_per_cell));
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
if (indices.size() <= 100)
{
double dof_values[100];
{
Assert (indices.size() % dofs_per_cell == 0,
ExcNotMultiple(indices.size(), dofs_per_cell));
- Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
+ Assert (this->update_flags & update_hessians,
+ ExcAccessToUninitializedField("update_hessians"));
if (indices.size() <= 100)
{
double dof_values[100];
{
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (this->update_flags & update_normal_vectors,
- typename FEVB::ExcAccessToUninitializedField());
+ typename FEVB::ExcAccessToUninitializedField("update_normal_vectors"));
return this->normal_vectors;
}
}
+namespace
+{
+ // Reset a std::auto_ptr. If we can, do not de-allocate the previously
+ // held memory but re-use it for the next item to avoid the repeated
+ // memory allocation. We do this because FEValues objects are heavily
+ // used in multithreaded contexts where memory allocations are evil.
+ template <typename Type, typename Pointer, typename Iterator>
+ void
+ reset_pointer_in_place_if_possible
+ (std::auto_ptr<Pointer> &present_cell,
+ const Iterator &new_cell)
+ {
+ // see if the existing pointer is non-null and if the type of
+ // the old object pointed to matches that of the one we'd
+ // like to create
+ if (present_cell.get()
+ &&
+ (typeid(*present_cell.get()) == typeid(Type)))
+ {
+ // call destructor of the old object
+ static_cast<const Type*>(present_cell.get())->~Type();
+
+ // then construct a new object in-place
+ new(const_cast<void *>(static_cast<const void *>(present_cell.get()))) Type(new_cell);
+ }
+ else
+ // if the types don't match, there is nothing we can do here
+ present_cell.reset (new Type(new_cell));
+ }
+}
+
template <int dim, int spacedim>
void FEValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
+ // destruction of the current object
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
+ (this->present_cell, cell);
+
// this was the part of the work
// that is dependent on the actual
// data type of the iterator. now
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::template
- CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > (cell));
+ // destruction of the current object
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > >
+ (this->present_cell, cell);
// this was the part of the work
// that is dependent on the actual
{
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (this->update_flags & update_boundary_forms,
- typename FEVB::ExcAccessToUninitializedField());
+ typename FEVB::ExcAccessToUninitializedField("update_boundary_forms"));
return this->boundary_forms;
}
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
+ // destruction of the current object
this->maybe_invalidate_previous_present_cell (cell);
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::template
- CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > (cell));
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > >
+ (this->present_cell, cell);
// this was the part of the work
// that is dependent on the actual
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
+ // destruction of the current object
this->maybe_invalidate_previous_present_cell (cell);
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
+ (this->present_cell, cell);
// this was the part of the work
// that is dependent on the actual
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
+ // destruction of the current object
this->maybe_invalidate_previous_present_cell (cell);
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::template
- CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > (cell));
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template CellIterator<TriaIterator<DoFCellAccessor<DH, lda> > > >
+ (this->present_cell, cell);
// this was the part of the work
// that is dependent on the actual
// care that old object gets
// destroyed and also that this
// object gets destroyed in the
- // destruction of this class
+ // destruction of the current object
this->maybe_invalidate_previous_present_cell (cell);
- this->present_cell.reset
- (new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
+ reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
+ (this->present_cell, cell);
// this was the part of the work
// that is dependent on the actual
case mapping_covariant:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d=0; d<dim; ++d)
case mapping_contravariant:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d=0; d<dim; ++d)
case mapping_piola:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d=0; d<dim; ++d)
case mapping_covariant:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_contravariant:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_covariant_gradient:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_contravariant_gradient:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_piola:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_piola_gradient:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
for (unsigned int i=0; i<output.size(); ++i)
for (unsigned int d1=0; d1<dim; ++d1)
case mapping_contravariant:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
output[i] = apply_transformation(data.contravariant[i], input[i]);
case mapping_piola:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
Assert (rank==1, ExcMessage("Only for rank 1"));
+ if (rank!=1)
+ return;
+
for (unsigned int i=0; i<output.size(); ++i)
{
output[i] = apply_transformation(data.contravariant[i], input[i]);
case mapping_covariant:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
output[i] = apply_transformation(data.covariant[i], input[i]);
case mapping_contravariant_gradient:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (rank==2, ExcMessage("Only for rank 2"));
for (unsigned int i=0; i<output.size(); ++i)
case mapping_covariant_gradient:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (rank==2, ExcMessage("Only for rank 2"));
for (unsigned int i=0; i<output.size(); ++i)
case mapping_piola_gradient:
{
Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
Assert (rank==2, ExcMessage("Only for rank 2"));
for (unsigned int i=0; i<output.size(); ++i)
case mapping_covariant:
{
Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
for (unsigned int i=0; i<output.size(); ++i)
output[i] = apply_transformation(data.covariant[i], input[i]);
const double eps = 1.e-11;
const unsigned int newton_iteration_limit = 20;
- unsigned int newton_iteration=0;
- double last_f_weighted_norm = -1./0.;
+ unsigned int newton_iteration = 0;
+ double last_f_weighted_norm;
do
{
#ifdef DEBUG_TRANSFORM_REAL_TO_UNIT_CELL
{
// Determine number of cells and vertices
const unsigned int
- n_cells = static_cast<unsigned int>(std::floor (half_length /
+ n_cells = static_cast<unsigned int>(std::ceil (half_length /
std::max (radius_0,
- radius_1) +
- 0.5));
+ radius_1)));
const unsigned int n_vertices = 4 * (n_cells + 1);
std::vector<Point<3> > vertices_tmp(n_vertices);
}
+for (deal_II_space_dimension : SPACE_DIMENSIONS)
+{
+
+ parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator
+ find_active_cell_around_point (const parallel::distributed::Triangulation<deal_II_space_dimension> &,
+ const Point<deal_II_space_dimension> &p);
+
+
+ std::pair<parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator, Point<deal_II_space_dimension> >
+ find_active_cell_around_point (const Mapping<deal_II_space_dimension> &,
+ const parallel::distributed::Triangulation<deal_II_space_dimension> &,
+ const Point<deal_II_space_dimension> &);
+}
+
for (deal_II_dimension : DIMENSIONS ; deal_II_space_dimension : SPACE_DIMENSIONS)
{
bool ConstraintMatrix::are_identity_constrained (const size_type index1,
- const size_type index2) const
+ const size_type index2) const
{
if (is_constrained(index1) == true)
{
// return if an entry for this line was found and if it has only one
// entry equal to 1.0 and that one is index2
return ((p.entries.size() == 1) &&
- (p.entries[0].first == index2) &&
- (p.entries[0].second == 1.0));
+ (p.entries[0].first == index2) &&
+ (p.entries[0].second == 1.0));
}
else if (is_constrained(index2) == true)
{
// return if an entry for this line was found and if it has only one
// entry equal to 1.0 and that one is index1
return ((p.entries.size() == 1) &&
- (p.entries[0].first == index1) &&
- (p.entries[0].second == 1.0));
+ (p.entries[0].first == index1) &&
+ (p.entries[0].second == 1.0));
}
else
return false;
+void
+ConstraintMatrix::resolve_indices (std::vector<types::global_dof_index> &indices) const
+{
+ const unsigned int indices_size = indices.size();
+ const std::vector<std::pair<types::global_dof_index,double> > * line_ptr;
+ for (unsigned int i=0; i<indices_size; ++i)
+ {
+ line_ptr = get_constraint_entries(indices[i]);
+ // if the index is constraint, the constraints indices are added to the
+ // indices vector
+ if (line_ptr!=NULL)
+ {
+ const unsigned int line_size = line_ptr->size();
+ for (unsigned int j=0; j<line_size; ++j)
+ indices.push_back((*line_ptr)[j].first);
+ }
+ }
+
+ // keep only the unique elements
+ std::sort(indices.begin(),indices.end());
+ std::vector<types::global_dof_index>::iterator it;
+ it = std::unique(indices.begin(),indices.end());
+ indices.resize(it-indices.begin());
+}
+
// explicit instantiations
#include <iostream>
#include <list>
#include <typeinfo>
+#include <vector>
DEAL_II_NAMESPACE_OPEN
template <class Matrix>
void SparseDirectMUMPS::initialize_matrix (const Matrix &matrix)
{
+ Assert(matrix.n() == matrix.m(), ExcMessage("Matrix needs to be square."));
+
+
// Check we haven't been here before:
Assert (initialize_called == false, ExcInitializeAlreadyCalled());
// Hand over matrix and right-hand side
initialize_matrix (matrix);
+ copy_rhs_to_mumps(vector);
+}
+
+void SparseDirectMUMPS::copy_rhs_to_mumps(const Vector<double> &new_rhs)
+{
+ Assert(n == new_rhs.size(), ExcMessage("Matrix size and rhs length must be equal."));
+
if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
{
- // Object denoting a MUMPS data structure
- rhs = new double[n];
-
+ rhs.resize(n);
for (size_type i = 0; i < n; ++i)
- rhs[i] = vector (i);
+ rhs[i] = new_rhs (i);
- id.rhs = rhs;
+ id.rhs = &rhs[0];
}
}
void SparseDirectMUMPS::copy_solution (Vector<double> &vector)
{
+ Assert(n == vector.size(), ExcMessage("Matrix size and solution vector length must be equal."));
+ Assert(n == rhs.size(), ExcMessage("Class not initialized with a rhs vector."));
+
// Copy solution into the given vector
if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
{
for (size_type i=0; i<n; ++i)
vector(i) = rhs[i];
- delete[] rhs;
+ rhs.resize(0); // remove rhs again
}
}
void SparseDirectMUMPS::solve (Vector<double> &vector)
{
+ //TODO: this could be implemented similar to SparseDirectUMFPACK where
+ // the given vector will be used as the RHS. Sadly, there is no easy
+ // way to do this without breaking the interface.
+
// Check that the solver has been initialized by the routine above:
Assert (initialize_called == true, ExcNotInitialized());
Assert (nz != 0, ExcNotInitialized());
// Start solver
- id.job = 6;
+ id.job = 6; // 6 = analysis, factorization, and solve
dmumps_c (&id);
copy_solution (vector);
}
// and that the matrix has at least one nonzero element:
Assert (nz != 0, ExcNotInitialized());
- // Hand over right-hand side
- if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
- {
- // Object denoting a MUMPS data structure:
- rhs = new double[n];
-
- for (size_type i = 0; i < n; ++i)
- rhs[i] = src (i);
+ Assert(n == dst.size(), ExcMessage("Destination vector has the wrong size."));
+ Assert(n == src.size(), ExcMessage("Source vector has the wrong size."));
- id.rhs = rhs;
- }
+ // Hand over right-hand side
+ copy_rhs_to_mumps(src);
// Start solver
id.job = 3;
#ifdef DEAL_II_WITH_MUMPS
#define InstantiateMUMPS(MATRIX) \
template \
- void SparseDirectMUMPS::initialize (const MATRIX &, const Vector<double> &);
+ void SparseDirectMUMPS::initialize (const MATRIX &, const Vector<double> &);\
+ template \
+ void SparseDirectMUMPS::initialize (const MATRIX &);
InstantiateMUMPS(SparseMatrix<double>)
InstantiateMUMPS(SparseMatrix<float>)
false),
cell_to_patch_index_map (&cell_to_patch_index_map)
{}
-
-
-
- /**
- * Dummy function used for WorkStream.
- */
- template <int dim, int spacedim>
- void
- copy(const DataOutBase::Patch<dim,spacedim> &patch) {}
}
}
(*data.cell_to_patch_index_map)[cell_and_index->first->level()][cell_and_index->first->index()];
// did we mess up the indices?
Assert(patch_idx < patches.size(), ExcInternalError());
-
+
// Put the patch in the patches vector
patches[patch_idx] = patch;
patches[patch_idx].patch_index = patch_idx;
std_cxx1x::bind(&DataOut<dim,DH>::build_one_patch,
this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3,
curved_cell_region,std_cxx1x::ref(this->patches)),
- std_cxx1x::bind(&internal::DataOut::copy<dim,DH::space_dimension>,
- std_cxx1x::_1),
+ // no copy-local-to-global function needed here
+ std_cxx1x::function<void (const ::dealii::DataOutBase::Patch<DH::dimension, DH::space_dimension> &)>(),
thread_data,
- sample_patch);
+ sample_patch,
+ // experimenting shows that we can make things run a bit
+ // faster if we increase the number of cells we work on
+ // per item (i.e., WorkStream's chunk_size argument,
+ // about 10% improvement) and the items in flight at any
+ // given time (another 5% on the testcase discussed in
+ // @ref workstream_paper, on 32 cores) and if
+ 8*multithread_info.n_threads(),
+ 64);
}
{
CopyData() {}
};
-
- void copier(CopyData const &) {}
}
}
std_cxx1x::cref(mapping),
std_cxx1x::cref(dof_handler),
std_cxx1x::cref(solution),component)),
- static_cast<std_cxx1x::function<void (internal::Assembler::CopyData const &)> >
- (internal::Assembler::copier),internal::Assembler::Scratch (),
- internal::Assembler::CopyData ());
+ std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
+ internal::Assembler::Scratch (),internal::Assembler::CopyData ());
}
template
void interpolate
- (const Mapping<DoFHandler<deal_II_dimension,deal_II_space_dimension>::dimension,DoFHandler<deal_II_dimension,deal_II_space_dimension>::space_dimension>&,
+ (const Mapping<deal_II_dimension,deal_II_space_dimension> &,
const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
const Function<deal_II_space_dimension>&,
VEC&);
##
## ---------------------------------------------------------------------
-IF(NOT DEFINED DEAL_II_BINARY_DIR)
+#
+# This is a small project that provides some custom targets that need a
+# working, independent subproject because they are called back during
+# configure phase.
+#
+
+IF(NOT DEFINED TEST_DIR)
MESSAGE(FATAL_ERROR "\n
The testsuite cannot be set up as an independent project.
Please configure \"deal.II\" directly instead.\n\n"
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
PROJECT(testsuite NONE)
-#
-# This is a small project that provides some custom targets that need a
-# working, independent subproject because they are called back during
-# configure phase.
-#
-
-# Setup tests:
-ADD_CUSTOM_TARGET(setup_tests
- COMMAND ${CMAKE_COMMAND}
- --build ${DEAL_II_BINARY_DIR} --target setup_tests
- )
-
# Regenerate tests (run "make rebuild_cache" in subprojects):
ADD_CUSTOM_TARGET(regen_tests)
# Clean all tests
ADD_CUSTOM_TARGET(clean_tests)
-# Remove all tests:
-ADD_CUSTOM_TARGET(prune_tests)
-
-#
-# Glob together a list of all subfolders to set up:
-#
-
FILE(GLOB _categories RELATIVE ${TEST_DIR} ${TEST_DIR}/*)
SET(_categories all-headers build_tests mesh_converter ${_categories})
LIST(REMOVE_DUPLICATES _categories)
-#
-# Define a subproject for every enabled category:
-#
-
FOREACH(_category ${_categories})
IF( EXISTS ${CMAKE_SOURCE_DIR}/${_category}/CMakeLists.txt OR
EXISTS ${TEST_DIR}/${_category}/CMakeLists.txt )
)
ADD_DEPENDENCIES(clean_tests clean_tests_${_category})
- ADD_CUSTOM_TARGET(prune_tests_${_category}
- COMMAND ${CMAKE_COMMAND} -E remove_directory
- ${CMAKE_BINARY_DIR}/${_category}
- )
- ADD_DEPENDENCIES(prune_tests prune_tests_${_category})
-
ENDIF()
ENDFOREACH()