- double norm (const Vector &v) {
+ double norm (const Vector &v)
{
double s = 0;
for (unsigned int i=0; itutorial programs on the use of this
- * library.
+ * documentation. Documentation on other aspects, such as the build
+ * system, can be found elsewhere. In addition, there are
+ * Tutorial programs on the use of the library.
*
* Many of the classes in the deal.II library can be grouped into modules (see
* the Modules page or the corresponding entry in
diff --git a/deal.II/doc/doxygen/headers/tutorial.h b/deal.II/doc/doxygen/headers/tutorial.h
deleted file mode 100644
index 0cb94932d6..0000000000
--- a/deal.II/doc/doxygen/headers/tutorial.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2005 - 2013 by the deal.II authors
-//
-// This file is part of the deal.II library.
-//
-// The deal.II library is free software; you can use it, redistribute
-// it, and/or modify it under the terms of the GNU Lesser General
-// Public License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// The full text of the license can be found in the file LICENSE at
-// the top level of the deal.II distribution.
-//
-// ---------------------------------------------------------------------
-
-
-/**
- * @page Tutorial Tutorial programs
- *
- * The tutorial is a separate part of the documentation for deal.II. It
- * consists of a collection of small programs, each more or less built atop
- * previous ones. They demonstrate various aspects of the library. A more
- * detailed overview can be found on this
- * page that also includes short summaries of what each of the tutorial
- * programs are supposed to demonstrate, as well as a list of the programs
- * sorted by topic.
- */
diff --git a/deal.II/doc/doxygen/scripts/make_toc.pl b/deal.II/doc/doxygen/scripts/make_toc.pl
deleted file mode 100644
index 1b1fbfe84c..0000000000
--- a/deal.II/doc/doxygen/scripts/make_toc.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-## ---------------------------------------------------------------------
-## $Id$
-##
-## Copyright (C) 2006 - 2013 by the deal.II authors
-##
-## This file is part of the deal.II library.
-##
-## The deal.II library is free software; you can use it, redistribute
-## it, and/or modify it under the terms of the GNU Lesser General
-## Public License as published by the Free Software Foundation; either
-## version 2.1 of the License, or (at your option) any later version.
-## The full text of the license can be found in the file LICENSE at
-## the top level of the deal.II distribution.
-##
-## ---------------------------------------------------------------------
-
-$/ = undef;
-
-# Read source for web page
-open TOC, ";
-close TOC;
-
-# Read generated map file
-open MAP, ";
-close MAP;
-
-# Insert contents of map file for @@MAP@@
-$toc =~ s/\@\@MAP\@\@/$map/;
-
-print $toc;
diff --git a/deal.II/doc/doxygen/scripts/mod_footer.pl b/deal.II/doc/doxygen/scripts/mod_footer.pl.in
similarity index 91%
rename from deal.II/doc/doxygen/scripts/mod_footer.pl
rename to deal.II/doc/doxygen/scripts/mod_footer.pl.in
index 149545d707..ab562cbd71 100644
--- a/deal.II/doc/doxygen/scripts/mod_footer.pl
+++ b/deal.II/doc/doxygen/scripts/mod_footer.pl.in
@@ -3,7 +3,7 @@ use Sys::Hostname;
my $host = hostname;
my $hosting = << 'EOT'
- Hosting provided by
+ Hosting provided by
EOT
diff --git a/deal.II/doc/doxygen/scripts/mod_header.pl b/deal.II/doc/doxygen/scripts/mod_header.pl.in
similarity index 100%
rename from deal.II/doc/doxygen/scripts/mod_header.pl
rename to deal.II/doc/doxygen/scripts/mod_header.pl.in
diff --git a/deal.II/doc/doxygen/scripts/steps.pl b/deal.II/doc/doxygen/scripts/steps.pl
index 7384b1e7f2..72e0e50a28 100644
--- a/deal.II/doc/doxygen/scripts/steps.pl
+++ b/deal.II/doc/doxygen/scripts/steps.pl
@@ -16,6 +16,16 @@
use strict;
+my $tutorial_file = shift;
+open TUTORIAL, "<$tutorial_file";
+
+# Print the first part of tutorial.h.in
+while (my $line = )
+{
+ last if($line =~ m/\@\@MAP\@\@/);
+ print $line;
+}
+
# List of additional node attributes to highlight purpose and state of the example
my %style = (
"basic" => ',height=.8,width=.8,shape="octagon",fillcolor="green"',
@@ -26,9 +36,7 @@ my %style = (
"unfinished" => ',height=.25,width=.25,style="dashed"'
);
-
# Print a preamble setting common attributes
-
print << 'EOT'
digraph StepsMap
{
@@ -65,7 +73,7 @@ foreach $step (@ARGV)
close TF;
chop $tooltip;
- printf "Step$number [label=\"$number\", URL=\"../deal.II/step_$number.html\", tooltip=\"$tooltip\"";
+ printf "Step$number [label=\"$number\", URL=\"\\ref step_$number\", tooltip=\"$tooltip\"";
# read first line of 'kind' file
@@ -106,3 +114,9 @@ foreach $step (@ARGV)
print "}\n";
+# Print the rest of tutorial.h.in
+while (my $line = )
+{
+ print $line;
+}
+close TUTORIAL;
diff --git a/deal.II/doc/doxygen/stylesheet.css b/deal.II/doc/doxygen/stylesheet.css
index 5ac8648c74..7002ba8acd 100644
--- a/deal.II/doc/doxygen/stylesheet.css
+++ b/deal.II/doc/doxygen/stylesheet.css
@@ -4,3 +4,18 @@
background-color: #0000ff;
color: #80ff00;
}
+
+table.tutorial {
+ color: black;
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+div.tutorial {
+ color: black;
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 50px;
+ font-size: 95%;
+}
diff --git a/deal.II/doc/doxygen/tutorial/CMakeLists.txt b/deal.II/doc/doxygen/tutorial/CMakeLists.txt
index acb617e981..6af4da8c98 100644
--- a/deal.II/doc/doxygen/tutorial/CMakeLists.txt
+++ b/deal.II/doc/doxygen/tutorial/CMakeLists.txt
@@ -16,69 +16,34 @@
#
-# Prepare steps.png and steps.cmapx:
+# Prepare tutorial.h:
#
+
ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
COMMAND ${PERL_EXECUTABLE}
ARGS
${CMAKE_SOURCE_DIR}/doc/doxygen/scripts/steps.pl
+ ${CMAKE_CURRENT_SOURCE_DIR}/tutorial.h.in
${DEAL_II_STEPS}
- > ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
- )
-ADD_CUSTOM_COMMAND(
- OUTPUT
- ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- COMMAND ${DOXYGEN_DOT_EXECUTABLE}
- ARGS
- -Tpng -o ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- -Tcmapx -o ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ > ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/steps.dot
+ ${DEAL_II_STEPS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/tutorial.h.in
)
-
-#
-# Prepare toc.html:
-#
-CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/toc.html.in
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html.in
- COPYONLY
- )
-ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- COMMAND ${PERL_EXECUTABLE}
- ARGS
- ${CMAKE_SOURCE_DIR}/doc/doxygen/scripts/make_toc.pl
- > ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- WORKING_DIRECTORY
- ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html.in
- ${CMAKE_CURRENT_BINARY_DIR}/steps.cmapx
- )
-
-
-#
-# TODO:
-# Are toc-list.html and toc-topics.html really generated by hand?
-#
-
-
#
# A target for the preparation of all the stuff happening in here...
#
+
ADD_CUSTOM_TARGET(tutorial
- DEPENDS
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tutorial.h
)
#
# Prepare the steps for documentation generation
#
+
FOREACH(_step ${DEAL_II_STEPS})
GET_FILENAME_COMPONENT(_step "${_step}" NAME)
@@ -118,20 +83,3 @@ FOREACH(_step ${DEAL_II_STEPS})
)
ADD_DEPENDENCIES(tutorial tutorial_${_step})
ENDFOREACH()
-
-#
-# Install all bits:
-#
-
-INSTALL(FILES
- index.html
- navbar.html
- title.html
- toc-list.html
- toc-topics.html
- ${CMAKE_CURRENT_BINARY_DIR}/steps.png
- ${CMAKE_CURRENT_BINARY_DIR}/toc.html
- DESTINATION ${DEAL_II_DOCHTML_RELDIR}/doxygen/tutorial
- COMPONENT documentation
- )
-
diff --git a/deal.II/doc/doxygen/tutorial/index.html b/deal.II/doc/doxygen/tutorial/index.html
deleted file mode 100644
index a6c308ae7b..0000000000
--- a/deal.II/doc/doxygen/tutorial/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-Step-by-Step Examples
-
-
-
-
-
-
-
-
-
The deal.II Tutorial
-Your browser does not seem to understand frames. A version of this
-tutorial that does not use frames can be found
-here.
-
-
-
-
-
-
-
-
diff --git a/deal.II/doc/doxygen/tutorial/navbar.html b/deal.II/doc/doxygen/tutorial/navbar.html
deleted file mode 100644
index b88c2c9818..0000000000
--- a/deal.II/doc/doxygen/tutorial/navbar.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-Step-by-Step Examples
-
-
-
-
-
-
-
-
-
-
Associate degrees of freedom to
- each vertex and compute the resulting sparsity pattern of
- matrices. Show that renumbering reduces the bandwidth of
- matrices significantly, i.e. clusters nonzero entries around the
- diagonal.
-
This example is programmed in a
- way that it is independent of the dimension for which we want to
- solve Laplace's equation; we will solve the equation in 2D and
- 3D, although the program is exactly the same. Non-constant right
- hand side function. Non-homogeneous boundary values.
-
Computations on successively
- refined grids. Reading a grid from disk. Some optimizations.
- Using assertions. Non-constant coefficient in
- the elliptic operator (yielding the extended Poisson
- equation). Preconditioning the CG solver for the
- linear system of equations.
-
Helmholtz
- equation. Non-homogeneous Neumann boundary conditions and
- boundary integrals. Verification of correctness of computed
- solutions. Computing the error between exact and numerical
- solution and output of the data in tables. Using counted pointers.
-
The elasticity equations will be
- solved instead of Laplace's equation. The solution is
- vector-valued and the equations form a system with as many
- equations as the dimension of the space in which it is posed.
-
Linear advection equation, assembling
- the system of equations in parallel using multi-threading,
- implementing a refinement criterion based on a finite difference
- approximation of the gradient.
-
-
A time dependent problem; using a much
- simplified version of implementing elasticity; moving meshes; handling
- large scale output of parallel programs.
-
Mixed finite elements. Using block
- matrices and block vectors to define more complicated solvers and
- preconditioners working on the Schur complement.
-
The time dependent two-phase flow in
- porous media. Extensions of mixed Laplace discretizations. More
- complicated block solvers. Simple time stepping.
-
Solving the Stokes equations of slow fluid flow on adaptive
- meshes. More on Schur complement solvers. Advanced use of the
- ConstraintMatrix class.
-
A massively parallel solver for time-dependent Stokes flow driven
- by temperature differences in a fluid. Adapting methods for real-world
- equations.
-
Solving Poisson's equation once more, this time with the
- interior penalty method, one of the discontinous Galerkin
- methods developed for this problem. Error estimator, adaptive
- meshes, and multigrid preconditioner, all using the MeshWorker
- framework.
-
Explicit time stepping for the Sine–Gordon equation based on
- a diagonal mass matrix. Efficient implementation of (nonlinear) finite
- element operators.
-
New to deal.II? You might want to start with tutorial Step-1 and work your way up to Step-5.
-At that point you can explore what features you are interested in and look at the large collection
-of programs listed below.
-
-
-
-The deal.II tutorial contains a collection of
-programs, each more
-or less built atop of previous ones, which demonstrate various
-aspects of the library. Each such example has the following structure:
-
-
Introduction: What the program does, including
- the mathematical model, and
- what programming techniques are new.
-
The commented program: An extensively documented listing of the
- source code.
-
Results: The output of the program, with comments and
- interpretation.
-
The plain program: The source code stripped of
- all comments.
-
-
-
-
-You can browse the available tutorial programs
-
-
as a graph (see below) that shows how tutorial programs build upon each other.
-
as a list that provides a short
- synopsis of each program.
-
-The programs are in the examples/ directory of your local deal.II
-installation. After compiling the library itself, if you go into one of the
-tutorial directories, you can compile
-the program by typing make, and run it
-using make run. The latter command also compiles the program
-if that has not already been done. The Makefiles in the different
-directories are based on the small program Makefile template described
-in this section.
-
-
-
-
-
Connections between tutorial programs
-
-The following graph shows the connections between tutorial programs and
-how they build on each other.
-Click on any of the boxes to go to one of the programs. If you hover
-your mouse pointer over a box, a brief description of the program
-should appear.
-
-
-
-@@MAP@@
-
-
-
-Legend:
-Green octagons: programs that show basic techniques;
-Orange boxes: advanced techniques;
-Yellow: applications in fluid dynamics;
-Light blue: applications in solid mechanics;
-Dark blue boxes: time dependent problems.
-
-
-
-
-
-The deal.II group
-
-
diff --git a/deal.II/doc/doxygen/tutorial/tutorial.h.in b/deal.II/doc/doxygen/tutorial/tutorial.h.in
new file mode 100644
index 0000000000..d7495be2a8
--- /dev/null
+++ b/deal.II/doc/doxygen/tutorial/tutorial.h.in
@@ -0,0 +1,959 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2005 - 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+/**
+ * @page Tutorial Tutorial programs
+ *
+ * New to deal.II? You might want to start with tutorial Step-1 and work
+ * your way up to Step-5. At that point you can explore what features you
+ * are interested in and look at the large collection of programs listed
+ * below.
+ *
+ * The deal.II tutorial contains a collection of programs, each more or
+ * less built atop of previous ones, which demonstrate various aspects of
+ * the library. Each such example has the following structure:
+ *
+ *
Introduction: What the program does, including
+ * the mathematical model, and
+ * what programming techniques are new.
+ *
The commented program: An extensively documented listing of the
+ * source code.
+ *
Results: The output of the program, with comments and
+ * interpretation.
+ *
The plain program: The source code stripped of
+ * all comments.
+ *
+ * You can browse the available tutorial programs
+ *
+ *
as a graph that shows how tutorial programs build upon each other.
+ *
as a list that provides a short
+ * synopsis of each program.
+ *
+ * Some of the programs also jointly form
+ * the geodynamics
+ * demonstration suite.
+ *
+ * The programs are in the examples/ directory of your local
+ * deal.II installation. After compiling the library itself, if you go into
+ * one of the tutorial directories, you can configure the program by typing
+ * cmake ., build it via make and run it using
+ * make run. The latter command also compiles the program if
+ * that has not already been done. The CMakefiles.txt files in the
+ * different directories are based on the small program Makefile template
+ * described in this
+ * section.
+ *
+ *
+ *
Connections between tutorial programs
+ *
+ * The following graph shows the connections between tutorial programs and
+ * how they build on each other.
+ * Click on any of the boxes to go to one of the programs. If you hover
+ * your mouse pointer over a box, a brief description of the program
+ * should appear.
+ * @dot
+@@MAP@@
+ * @enddot
+ *
+ * Legend:
+ * Green octagons: programs that show basic techniques;
+ * Orange boxes: advanced techniques;
+ * Yellow: applications in fluid dynamics;
+ * Light blue: applications in solid mechanics;
+ * Dark blue boxes: time dependent problems.
+ *
+ *
+ *
Tutorial programs listed by number
+ *
+ *
+ *
+ *
Step-1
+ *
Creating a grid. A simple way to write it to a file.
+ *
+ *
+ *
+ *
Step-2
+ *
Associate degrees of freedom to
+ * each vertex and compute the resulting sparsity pattern of
+ * matrices. Show that renumbering reduces the bandwidth of
+ * matrices significantly, i.e. clusters nonzero entries around the
+ * diagonal.
+ *
This example is programmed in a
+ * way that it is independent of the dimension for which we want to
+ * solve Laplace's equation; we will solve the equation in 2D and
+ * 3D, although the program is exactly the same. Non-constant right
+ * hand side function. Non-homogeneous boundary values.
+ *
+ *
+ *
+ *
Step-5
+ *
Computations on successively
+ * refined grids. Reading a grid from disk. Some optimizations.
+ * Using assertions. Non-constant coefficient in
+ * the elliptic operator (yielding the extended Poisson
+ * equation). Preconditioning the CG solver for the
+ * linear system of equations.
+ *
+ *
+ *
+ *
Step-6
+ *
Adaptive local
+ * refinement. Handling of hanging nodes. Higher order elements.
+ * Catching exceptions in the main; function.
+ *
+ *
+ *
+ *
Step-7
+ *
Helmholtz
+ * equation. Non-homogeneous Neumann boundary conditions and
+ * boundary integrals. Verification of correctness of computed
+ * solutions. Computing the error between exact and numerical
+ * solution and output of the data in tables. Using counted pointers.
+ *
+ *
+ *
+ *
Step-8
+ *
The elasticity equations will be
+ * solved instead of Laplace's equation. The solution is
+ * vector-valued and the equations form a system with as many
+ * equations as the dimension of the space in which it is posed.
+ *
+ *
+ *
+ *
Step-9
+ *
Linear advection equation, assembling
+ * the system of equations in parallel using multi-threading,
+ * implementing a refinement criterion based on a finite difference
+ * approximation of the gradient.
+ *
+ *
+ *
Step-10
+ *
Higher order mappings. Do not
+ * solve equations, but rather compute the value of pi to high
+ * accuracy.
+ *
+ *
+ *
+ *
Step-11
+ *
Solving a Laplace problem with
+ * higher order mappings. Using strange constraints and
+ * intermediate representations of sparsity patterns.
+ *
+ *
+ *
+ *
Step-12
+ *
Discontinuous Galerkin methods for linear advection problems.
+ *
+ *
+ *
+ *
Step-13
+ *
Software design questions and
+ * how to write a modular, extensible finite element program.
+ *
+ *
+ *
+ *
Step-14
+ *
Duality based error estimators,
+ * more strategies to write a modular, extensible finite element
+ * program.
+ *
+ *
+ *
+ *
Step-15
+ *
A nonlinear elliptic problem: The minimal surface equation.
+ * Newton's method. Transferring a solution across mesh refinement.
+ *
+ *
+ *
+ *
Step-16
+ *
Multigrid preconditioning of the Laplace equation on adaptive
+ * meshes.
+ *
+ *
+ *
+ *
Step-17
+ *
Using PETSc for linear algebra; running
+ * in parallel on clusters of computers linked together by MPI.
+ *
+ *
+ *
+ *
Step-18
+ *
A time dependent problem; using a much
+ * simplified version of implementing elasticity; moving meshes; handling
+ * large scale output of parallel programs.
+ *
+ *
+ *
+ *
Step-19
+ *
Input parameter file handling. Merging
+ * output of a parallel program.
+ *
+ *
+ *
+ *
Step-20
+ *
Mixed finite elements. Using block
+ * matrices and block vectors to define more complicated solvers and
+ * preconditioners working on the Schur complement.
+ *
+ *
+ *
+ *
Step-21
+ *
The time dependent two-phase flow in
+ * porous media. Extensions of mixed Laplace discretizations. More
+ * complicated block solvers. Simple time stepping.
+ *
+ *
+ *
+ *
Step-22
+ *
Solving the Stokes equations of slow fluid flow on adaptive
+ * meshes. More on Schur complement solvers. Advanced use of the
+ * ConstraintMatrix class.
+ *
+ *
+ *
+ *
Step-23
+ *
Finally a "real" time dependent problem, the wave equation.
+ *
+ *
+ *
+ *
Step-24
+ *
A variant of step-23 with absorbing
+ * boundary conditions, and extracting practically useful data.
+ *
+ *
+ *
+ *
Step-25
+ *
The sine-Gordon
+ * soliton equation, which is a nonlinear variant of the time
+ * dependent wave equation covered in step-23 and step-24.
+ *
+ *
+ *
+ *
Step-27
+ *
hp finite element methods
+ *
+ *
+ *
Step-28
+ *
Multiple grids for solving a multigroup diffusion equation
+ * in nuclear physics simulating a nuclear reactor core
+ *
+ *
+ *
Step-29
+ *
Solving a complex-valued Helmholtz equation. Sparse direct
+ * solvers. Dealing with parameter files.
+ *
+ *
+ *
Step-30
+ *
Anisotropic refinement for DG finite element methods.
+ *
+ *
+ *
+ *
Step-31
+ *
Time-dependent Stokes flow driven by temperature
+ * differences in a fluid. Adaptive meshes that change between time
+ * steps.
+ *
+ *
+ *
+ *
Step-32
+ *
A massively parallel solver for time-dependent Stokes flow driven
+ * by temperature differences in a fluid. Adapting methods for real-world
+ * equations.
+ *
+ *
+ *
+ *
Step-33
+ *
A nonlinear hyperbolic conservation law: The Euler equations of
+ * compressible gas dynamics.
+ *
+ *
+ *
+ *
Step-34
+ *
Boundary element methods (BEM) of low order: Exterior irrotational
+ * flow. The ParsedFunction class.
+ *
+ *
+ *
+ *
Step-35
+ *
A projection solver for the Navier–Stokes equations.
+ *
+ *
+ *
+ *
Step-36
+ *
Using SLEPc for linear algebra; solving an eigenspectrum
+ * problem. The Schrödinger wave equation.
+ *
+ *
+ *
+ *
Step-37
+ *
Solving a Poisson problem with a multilevel preconditioner without
+ * explicitly storing the matrix (a matrix-free method).
+ *
+ *
+ *
+ *
Step-38
+ *
Solving the Laplace-Beltrami equation on curved manifolds embedded
+ * in higher dimensional spaces.
+ *
+ *
+ *
+ *
Step-39
+ *
Solving Poisson's equation once more, this time with the
+ * interior penalty method, one of the discontinous Galerkin
+ * methods developed for this problem. Error estimator, adaptive
+ * meshes, and multigrid preconditioner, all using the MeshWorker
+ * framework.
+ *
+ *
+ *
+ *
Step-40
+ *
Techniques for the massively parallel solution of the Laplace
+ * equation (up to 10,000s of processors).
+ *
+ *
+ *
+ *
Step-41
+ *
Solving the obstacle problem, a variational inequality.
+ *
+ *
+ *
+ *
Step-42
+ *
A solver for an elasto-plastic contact problem, running on
+ * parallel machines.
+ *
+ *
+ *
+ *
Step-43
+ *
Advanced techniques for the simulation of porous media flow.
+ *
+ *
+ *
+ *
Step-44
+ *
Finite strain hyperelasticity based on a three-field formulation.
+ *
+ *
+ *
+ *
Step-45
+ *
Periodic boundary conditions.
+ *
+ *
+ *
+ *
Step-46
+ *
Coupling different kinds of equations in different parts of the domain.
+ *
+ *
+ *
+ *
Step-48
+ *
Explicit time stepping for the Sine–Gordon equation based on
+ * a diagonal mass matrix. Efficient implementation of (nonlinear) finite
+ * element operators.
+ *
+ *
+ *
+ *
Step-49
+ *
Advanced mesh creation and manipulation techniques.
+ *
+ *
+ *
+ *
Step-51
+ *
Solving the convection-diffusion equation with a hyrbidizable
+ * discontinuous Galerkin method using face elements.
+ *
+ *
+ *
+ *
+ *
Tutorial programs grouped by topics
+ *
+ *
Basic techniques
+ *
+ *
+ *
+ *
Creating a grid. A simple way to write it to a file
+ *
Step-1
+ *
+ *
+ *
+ *
+ *
Degrees of freedom
+ *
Step-2
+ *
+ *
+ *
+ *
+ *
Solve the Laplace equation
+ *
Step-3
+ *
+ *
+ *
+ *
+ *
Dimension independent programming, non-zero data
+ *
Removed: With the switch of the testsuite to CMake, the old report_features
+ and build test facilities are removed.
+
+ (Matthias Maier, 2013/12/03)
+
+
Changed: The kinds of template arguments for the VectorTools::interpolate
function taking a Mapping as first argument has changed. This was done to
@@ -107,6 +113,16 @@ inconvenience this causes.
+
Improved: The build system now supports usage of the library
+ out of the build directory without prior installation. This is done by
+ exporting an additional project configuration just for the build directory.
+ Furthermore, a bunch of convenience targets get now defined that just build
+ individual components (such as just the documentation or the libraries), and
+ if CMAKE_INSTALL_PREFIX is set, also install that specific component.
+
+ (Matthias Maier, Luca Heltai, 2013/12/03)
+
+
Fixed: Missing instantiations of SparseDirectMUMPS have been added.
(Timo Heister, 2013/11/25)
@@ -230,6 +246,21 @@ inconvenience this causes.
Specific improvements
+
Fixed: Several functions in namespace GridTools were not instantiated
+ for parallel::distributed::Triangulation objects. This is now fixed.
+
+ (Denis Davydov, Wolfgang Bangerth, 2013/12/01)
+
+
+
Improved: The methods ConstraintMatrix::distribute_local_to_global
+ now use scratch data that is private to each thread instead of allocating
+ it for every cell anew. This gives better performance, in particular in
+ parallel, of these operations, while maintaining thread-safety (when
+ accessing non-overlapping rows, no race condition can exist).
+
+ (Martin Kronbichler, 2013/12/03)
+
+
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
diff --git a/deal.II/doc/publications/index.html b/deal.II/doc/publications/index.html
index bd0feb08cb..65522db8e5 100644
--- a/deal.II/doc/publications/index.html
+++ b/deal.II/doc/publications/index.html
@@ -250,6 +250,23 @@
+
+
+
+
Publications in 2014
+
+
+
+
T. Wick, G. Singh, M.F. Wheeler
+
+ Pressurized-Fracture propagation using a phase-field approach coupled to a reservoir simulator
+
+
+ SPE 168597-MS, SPE HFTC Proc. 2014.
+
+
+
+
Publications in 2013
@@ -505,6 +522,23 @@
Journal of Elasticity, in press, 2013.
+
S. Frei, T. Richter, T. Wick
+
+ Eulerian Techniques for Fluid-Structure Interactions - Part
+ I: Modeling and Simulation
+
+
+ ENUMATH Proc., submitted Nov 2013.
+
+
+
S. Frei, T. Richter, T. Wick
+
+ Eulerian Techniques for Fluid-Structure Interactions - Part II: Applications
+
+
+ ENUMATH Proc., submitted Nov 2013.
+
+
A. Geringer, B. Lenhof, S. Diebels
Macroscopic modeling of foams: an order-parameter
@@ -608,14 +642,21 @@
PhD thesis, University of Siegen, Germany, 2013.
+
K. Kumar, T. van Noorden, M. F. Wheeler, T. Wick
+
+ An ALE-based method for reaction-induced boundary movement towards clogging
+
+
+ ENUMATH Proc., submitted Nov 2013.
+
+
K. Kumar, M.F. Wheeler, T. Wick
- Reactive flow in a thin channel
-and reaction-induced boundary movement in
-a monolithic ALE framework
+ Reactive flow reaction-induced boundary movement in
+ a thin channel
- submitted to SISC, 2013.
+ SIAM J. Sci. Comput. 35(6), pp. B1235-B1266, 2013
B. Lenhof, A. Geringer, S. Diebels
@@ -679,12 +720,29 @@ a monolithic ALE framework
pp. 41-46, 2013.
+
T. Richter, T. Wick
+
+ Solid growth and clogging in fluid-structure interaction computed in ALE and fully Eulerian coordinates
+
+
+ submitted Oct 2013 (peer-reviewed journal)
+
+
+
T. Richter, T. Wick
+
+ On time discretizations of fluid-structure interactions
+
+
+ submitted Oct 2013 (book proceedings)
+
+
+
T. Richter, T. Wick
Optimal Control and Parameter Estimation for Stationary Fluid-Structure Interaction Problems
- SISC, accepted in May, 2013.
+ SIAM J. Sci. Comput., accepted in May, 2013.
S. Roy, L. Heltai, D. Drapaca, F. Costanzo
@@ -773,6 +831,8 @@ a monolithic ALE framework
ARMA Conference in San Francisco, Jun 23-26, 2013.
+
+
J. Weinbub, K. Rupp, S. Selberherr
ViennaX: a parallel plugin execution framework for
@@ -789,7 +849,7 @@ a monolithic ALE framework
and Mesh Adaptivity
- Comp. Mech., DOI: 10.1007/s00466-013-0890-3, 2013.
+ Computational Mechanics, DOI: 10.1007/s00466-013-0890-3, 2013.
T. Wick
@@ -798,7 +858,7 @@ a monolithic ALE framework
methods for fluid-structure interaction computations
- Comp. Mech., DOI: 10.1007/s00466-013-0866-3, 2013.
+ Computational Mechanics, DOI: 10.1007/s00466-013-0866-3, 2013.
T. Wick
diff --git a/deal.II/doc/readme.html b/deal.II/doc/readme.html
index 5ea8cc3d06..f4c41181f3 100644
--- a/deal.II/doc/readme.html
+++ b/deal.II/doc/readme.html
@@ -318,7 +318,7 @@
At this point, you have generated everything necessary to write
programs based on deal.II. If you are new to
deal.II, you may want to continue with the
- tutorial.
+ tutorial.
@@ -349,7 +349,7 @@
install both this readme, other installation instructions, as well as the
manual that documents
all functions and classes as well as
- the tutorial
+ the tutorial
of well-documented example programs (the "steps").
diff --git a/deal.II/doc/screen.css b/deal.II/doc/screen.css
index 2abc65f177..b13ec87ed6 100644
--- a/deal.II/doc/screen.css
+++ b/deal.II/doc/screen.css
@@ -254,20 +254,6 @@ pre.sample {
}
table.navbar { }
-table.tutorial {
- color: black;
- border: 1px solid #aaa;
- background-color: #f9f9f9;
- padding: 5px;
- font-size: 95%;
-}
-div.tutorial {
- color: black;
- border: 1px solid #aaa;
- background-color: #f9f9f9;
- padding: 50px;
- font-size: 95%;
-}
strong.red { color: #ff0000; }
code.program { color: #700000; }
diff --git a/deal.II/doc/users/cmake.html b/deal.II/doc/users/cmake.html
index 7a571607ef..1f2d695a10 100644
--- a/deal.II/doc/users/cmake.html
+++ b/deal.II/doc/users/cmake.html
@@ -206,34 +206,35 @@ cmake -DDEAL_II_WITH_MPI=ON <...>
Primary build targets
The current list of primary build targets can be queried via
- make info:
+ make help:
###
#
# The following targets are available (invoke via $ make <target>):
#
-# all - compiles the library and all enabled components
-# clean - removes all generated files
-# install - installs into CMAKE_INSTALL_PREFIX
-# help - prints a list of valid top level targets
-# info - prints this help message
+# all - compile the library and all enabled components
+# clean - remove all generated files
+# install - install into CMAKE_INSTALL_PREFIX
+# help - print this help message in the toplevel directory,
+# otherwise print a list of targets (in subdirectories)
#
-# edit_cache - runs ccmake for changing (cached) configuration variables
+# edit_cache - run ccmake for changing (cached) configuration variables
# and reruns the configure and generate phases of CMake
-# rebuild_cache - reruns the configure and generate phases of CMake
+# rebuild_cache - rerun the configure and generate phases of CMake
#
-# compat_files - builds and installs the 'compat_files' component
-# documentation - builds and installs the 'documentation' component
-# examples - builds and installs the 'examples' component
-# library - builds and installs the 'library' component
-# mesh_converter - builds and installs the 'mesh_converter' component
-# parameter_gui - builds and installs the 'parameter_gui' component
+# compat_files - build and install component 'compat_files'
+# documentation - build and install component 'documentation'
+# examples - build and install component 'examples'
+# library - build and install component 'library'
+# mesh_converter - build and install component 'mesh_converter'
+# parameter_gui - build and install component 'parameter_gui'
#
-# test - runs a minimal set of tests
+# test - run a minimal set of tests
#
-# setup_test - sets up the testsuite subprojects
-# clean_test - runs the 'clean' target in every testsuite subproject
-# prune_test - removes all testsuite subprojects
+# setup_tests - set up the testsuite subprojects
+# regen_tests - rerun configure stage in every testsuite subprojects
+# clean_tests - run the 'clean' target in every testsuite subproject
+# prune_tests - remove all testsuite subprojects
#
###
@@ -273,7 +274,7 @@ cmake -DDEAL_II_WITH_MPI=ON <...>
#
# Detailed information (compiler flags, feature configuration) can be found in detailed.log
#
-# Run $ make info to print a help message with a list of top level targets
+# Run $ make help to print a help message with a list of top level targets
#
###
diff --git a/deal.II/doc/users/cmakelists.html b/deal.II/doc/users/cmakelists.html
index 19d5686899..e6a45736ff 100644
--- a/deal.II/doc/users/cmakelists.html
+++ b/deal.II/doc/users/cmakelists.html
@@ -822,7 +822,6 @@ ${CMAKE_INSTALL_PREFIX}/
common/Make.global_options
common/scripts/expand_instantiations
common/scripts/make_dependencies
- common/scripts/report_features
Therefore, it should be sufficient to set D in the old
diff --git a/deal.II/doc/users/navbar.html b/deal.II/doc/users/navbar.html
index 8b55b4c263..411bf6cf72 100644
--- a/deal.II/doc/users/navbar.html
+++ b/deal.II/doc/users/navbar.html
@@ -40,7 +40,7 @@
Doxygen
- The tutorial is for new users of the
library. It explains the basic elements of finite element
programs based on the library, and provides small example
diff --git a/deal.II/examples/CMakeLists.txt b/deal.II/examples/CMakeLists.txt
index 3655a42bf1..45f41856a9 100644
--- a/deal.II/examples/CMakeLists.txt
+++ b/deal.II/examples/CMakeLists.txt
@@ -15,6 +15,8 @@
## ---------------------------------------------------------------------
IF(DEAL_II_COMPONENT_EXAMPLES)
+ MESSAGE(STATUS "Setup examples")
+
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION ${DEAL_II_EXAMPLES_RELDIR}
COMPONENT examples
@@ -42,4 +44,6 @@ IF(DEAL_II_COMPONENT_EXAMPLES)
PATTERN "untitled.geo" # step-49
PATTERN "untitled.msh" # step-49
)
+
+ MESSAGE(STATUS "Setup examples - Done")
ENDIF()
diff --git a/deal.II/examples/step-18/step-18.cc b/deal.II/examples/step-18/step-18.cc
index 0bd852c572..283419e941 100644
--- a/deal.II/examples/step-18/step-18.cc
+++ b/deal.II/examples/step-18/step-18.cc
@@ -1718,6 +1718,17 @@ namespace Step18
// to the vertex we consider at present, as they may or may not be ordered
// in the same order.
//
+ // This inconvenience could be avoided if finite elements have support
+ // points on vertices (which the one here has; for the concept of support
+ // points, see @ref GlossSupport "support points"). For such a case, one
+ // could construct a custom quadrature rule using
+ // FiniteElement::get_unit_support_points(). The first
+ // GeometryInfo@::vertices_per_cell*fe.dofs_per_vertex
+ // quadrature points will then correspond to the vertices of the cell and
+ // are ordered consistent with cell-@>vertex(i), taking into
+ // account that support points for vector elements will be duplicated
+ // fe.dofs_per_vertex times.
+ //
// Another point worth explaining about this short function is the way in
// which the triangulation class exports information about its vertices:
// through the Triangulation::n_vertices function, it
diff --git a/deal.II/examples/step-25/doc/intro.dox b/deal.II/examples/step-25/doc/intro.dox
index 41a133cc8c..e06d36fc27 100644
--- a/deal.II/examples/step-25/doc/intro.dox
+++ b/deal.II/examples/step-25/doc/intro.dox
@@ -11,7 +11,7 @@ extensively.
Rather facetiously, the sine-Gordon equation's moniker is a pun on the
so-called Klein-Gordon equation, which is a relativistic version of
-the Schrödinger equation for particles with non-zero mass. The resemblance is not just
+the Schrödinger equation for particles with non-zero mass. The resemblance is not just
superficial, the sine-Gordon equation has been shown to model some
unified-field phenomena such as interaction of subatomic particles
(see, e.g., Perring & Skyrme in Nuclear Physics 31) and the
diff --git a/deal.II/examples/step-36/doc/intro.dox b/deal.II/examples/step-36/doc/intro.dox
index c5e4aecf00..f0eb3867cb 100644
--- a/deal.II/examples/step-36/doc/intro.dox
+++ b/deal.II/examples/step-36/doc/intro.dox
@@ -53,7 +53,7 @@ for linear algebra contents.
Introduction
The basic equation of stationary quantum mechanics is the
-Schrödinger equation which models the motion of particles in an
+Schrödinger equation which models the motion of particles in an
external potential $V(\mathbf x)$. The particle is described by a wave
function $\Psi(\mathbf x)$ that satisfies a relation of the
(nondimensionalized) form
diff --git a/deal.II/examples/step-36/doc/tooltip b/deal.II/examples/step-36/doc/tooltip
index 3a5f92e61a..1e1a5da68b 100644
--- a/deal.II/examples/step-36/doc/tooltip
+++ b/deal.II/examples/step-36/doc/tooltip
@@ -1 +1 @@
-Finding eigenvalues of the Schrödinger equation.
+Finding eigenvalues of the Schrödinger equation.
diff --git a/deal.II/examples/step-37/doc/tooltip b/deal.II/examples/step-37/doc/tooltip
index 65cc3a07fc..83658ea2c4 100644
--- a/deal.II/examples/step-37/doc/tooltip
+++ b/deal.II/examples/step-37/doc/tooltip
@@ -1 +1 @@
-Matrix-free methods. Multigrid. Cell-based finite element operator.
+Matrix-free methods. Multigrid. Fast assembly techniques.
diff --git a/deal.II/examples/step-41/doc/intro.dox b/deal.II/examples/step-41/doc/intro.dox
index 84afbba1f6..62e8876b0b 100644
--- a/deal.II/examples/step-41/doc/intro.dox
+++ b/deal.II/examples/step-41/doc/intro.dox
@@ -1,6 +1,6 @@
-This program was contributed by Jörg Frohne (University of Siegen,
+This program was contributed by Jörg Frohne (University of Siegen,
Germany) while on a long-term visit to Texas A&M University.
This material is based upon work partly supported by ThyssenKrupp Steel Europe.
diff --git a/deal.II/examples/step-42/doc/intro.dox b/deal.II/examples/step-42/doc/intro.dox
index e9dbabb604..27ce612c59 100644
--- a/deal.II/examples/step-42/doc/intro.dox
+++ b/deal.II/examples/step-42/doc/intro.dox
@@ -1,6 +1,6 @@
-This program was contributed by Jörg Frohne (University of Siegen,
+This program was contributed by Jörg Frohne (University of Siegen,
Germany) while on a long-term visit to Texas A&M University, with significant
contributions by Timo Heister and Wolfgang Bangerth.
diff --git a/deal.II/examples/step-42/doc/results.dox b/deal.II/examples/step-42/doc/results.dox
index 59158fd480..73911f11fe 100644
--- a/deal.II/examples/step-42/doc/results.dox
+++ b/deal.II/examples/step-42/doc/results.dox
@@ -199,7 +199,7 @@ situations are concerned:
Extend the program from a static to a quasi-static situation, perhaps by
choosing a backward-Euler-scheme for the time discretization. Some theoretical
-results can be found in the PhD thesis by Jörg Frohne, FEM-Simulation
+results can be found in the PhD thesis by Jörg Frohne, FEM-Simulation
der Umformtechnik metallischer Oberflächen im Mikrokosmos, University
of Siegen, Germany, 2011.
diff --git a/deal.II/examples/step-48/doc/tooltip b/deal.II/examples/step-48/doc/tooltip
index b7f08a32cc..ffe23aeb00 100644
--- a/deal.II/examples/step-48/doc/tooltip
+++ b/deal.II/examples/step-48/doc/tooltip
@@ -1 +1 @@
-Parallelization via MPI. The wave equation, in linear and nonlinear variants. Mass lumping. Cell-based finite element operator.
+Parallelization via MPI. The wave equation, in linear and nonlinear variants. Mass lumping. Fast assembly techniques.
diff --git a/deal.II/include/deal.II/base/function_parser.h b/deal.II/include/deal.II/base/function_parser.h
index 0fff67c271..77858606fc 100644
--- a/deal.II/include/deal.II/base/function_parser.h
+++ b/deal.II/include/deal.II/base/function_parser.h
@@ -508,8 +508,8 @@ public:
/**
* Return all components of a
- * vector-valued function at a
- * given point.
+ * vector-valued function at the
+ * given point @p p.
*
* values shall have the
* right size beforehand,
diff --git a/deal.II/include/deal.II/base/parsed_function.h b/deal.II/include/deal.II/base/parsed_function.h
index 408ec9ae17..90a3202b50 100644
--- a/deal.II/include/deal.II/base/parsed_function.h
+++ b/deal.II/include/deal.II/base/parsed_function.h
@@ -221,8 +221,9 @@ namespace Functions
void parse_parameters(ParameterHandler &prm);
/**
- * Get one value at the given
- * point.
+ * Return all components of a
+ * vector-valued function at the
+ * given point @p p.
*/
virtual void vector_value (const Point &p,
Vector &values) const;
@@ -258,7 +259,7 @@ namespace Functions
* The object with which we do
* computations.
*/
- FunctionParser function_object;
+ FunctionParse function_object;
};
}
diff --git a/deal.II/include/deal.II/distributed/tria.h b/deal.II/include/deal.II/distributed/tria.h
index a4c0526529..1bfe32cd5a 100644
--- a/deal.II/include/deal.II/distributed/tria.h
+++ b/deal.II/include/deal.II/distributed/tria.h
@@ -706,17 +706,20 @@ namespace parallel
/**
- * Join faces in the p4est forest due to periodic boundary conditions.
+ * Join faces in the p4est forest for periodic boundary conditions. As a
+ * result, each pair of faces will differ by at most one refinement level
+ * and ghost neighbors will be available across these faces.
*
* The vector can be filled by the function
* GridTools::collect_periodic_faces.
*
* @todo At the moment just default orientation is implemented.
*
- * @note Before this function can be used the triangulation has to be
+ * @note Before this function can be used the Triangulation has to be
* initialized and must not be refined.
* Calling this function more than once is possible, but not recommended:
- * The function destroys and rebuilds the p4est forest each time it is called.
+ * The function destroys and rebuilds the p4est forest each time it is
+ * called.
*/
void
add_periodicity
diff --git a/deal.II/include/deal.II/fe/fe.h b/deal.II/include/deal.II/fe/fe.h
index 31fb8c8cb7..40b4c742c5 100644
--- a/deal.II/include/deal.II/fe/fe.h
+++ b/deal.II/include/deal.II/fe/fe.h
@@ -114,12 +114,12 @@ namespace hp
* FEValues fe_values (mapping, fe, dummy_quadrature,
* update_quadrature_points);
* fe_values.reinit (cell);
- * Point& mapped_point = fe_values.quadrature_point (i);
+ * Point mapped_point = fe_values.quadrature_point (i);
* @endcode
*
* Alternatively, the points can be transformed one-by-one:
* @code
- * const vector >& unit_points =
+ * const vector > &unit_points =
* fe.get_unit_support_points();
*
* Point mapped_point =
@@ -129,6 +129,13 @@ namespace hp
* If the mapping of all support points is needed, the first variant should
* be preferred for efficiency.
*
+ * @note Finite elements' implementation of the get_unit_support_points()
+ * returns these points in the same order as shape functions. As a consequence,
+ * the quadrature points accessed above are also ordered in this way. The
+ * order of shape functions is typically documented in the class documentation
+ * of the various finite element classes.
+ *
+ *
*
Notes on the implementation of derived classes
*
* The following sections list the information to be provided by
@@ -1315,7 +1322,7 @@ public:
/**
* Return the support points of the trial functions on the unit cell, if the
- * derived finite element defines some. Finite elements that allow some
+ * derived finite element defines them. Finite elements that allow some
* kind of interpolation operation usually have support points. On the other
* hand, elements that define their degrees of freedom by, for example,
* moments on faces, or as derivatives, don't have support points. In that
@@ -1327,6 +1334,20 @@ public:
* function.
*
* See the class documentation for details on support points.
+ *
+ * @note Finite elements' implementation of this function
+ * returns these points in the same order as shape functions. The
+ * order of shape functions is typically documented in the class documentation
+ * of the various finite element classes. In particular, shape functions (and
+ * consequently the mapped quadrature points discussed in the class documentation
+ * of this class) will then traverse first those shape functions
+ * located on vertices, then on lines, then on quads, etc.
+ *
+ * @note If this element implements support points, then it will return one
+ * such point per shape function. Since multiple shape functions may be defined
+ * at the same location, the support points returned here may be duplicated. An
+ * example would be an element of the kind FESystem(FE_Q(1),3)
+ * for which each support point would appear three times in the returned array.
*/
const std::vector > &
get_unit_support_points () const;
diff --git a/deal.II/include/deal.II/grid/grid_tools.h b/deal.II/include/deal.II/grid/grid_tools.h
index 61ce67c53d..29cefdfe52 100644
--- a/deal.II/include/deal.II/grid/grid_tools.h
+++ b/deal.II/include/deal.II/grid/grid_tools.h
@@ -1065,8 +1065,8 @@ namespace GridTools
/**
- * This function will collect periodic face pairs on the highest (i.e.
- * coarsest) mesh level.
+ * This function will collect periodic face pairs on the
+ * coarsest mesh level of the given @p container (a Triangulation or DoFHandler).
*
* Define a 'first' boundary as all boundary faces having boundary_id
* @p b_id1 and a 'second' boundary consisting of all faces belonging
@@ -1095,14 +1095,14 @@ namespace GridTools
*
* @author Daniel Arndt, Matthias Maier, 2013
*/
- template
- std::vector >
+ template
+ std::vector >
collect_periodic_faces
- (const DH &dof_handler,
+ (const CONTAINER &container,
const types::boundary_id b_id1,
const types::boundary_id b_id2,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset = dealii::Tensor<1,DH::space_dimension>());
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>());
/**
@@ -1116,8 +1116,7 @@ namespace GridTools
* face with local face index 2*dimension+1 and boundary
* indicator @p b_id.
*
- * This function will collect periodic face pairs on the highest (i.e.
- * coarsest) mesh level.
+ * This function will collect periodic face pairs on the coarsest mesh level.
*
* @note This version of collect_periodic_face_pairs will not work on
* meshes with cells not in @ref GlossFaceOrientation
@@ -1125,13 +1124,13 @@ namespace GridTools
*
* @author Daniel Arndt, Matthias Maier, 2013
*/
- template
- std::vector >
+ template
+ std::vector >
collect_periodic_faces
- (const DH &dof_handler,
+ (const CONTAINER &container,
const types::boundary_id b_id,
const int direction,
- const dealii::Tensor<1,DH::space_dimension> &offset = dealii::Tensor<1,DH::space_dimension>());
+ const dealii::Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>());
/**
diff --git a/deal.II/include/deal.II/lac/constraint_matrix.h b/deal.II/include/deal.II/lac/constraint_matrix.h
index 7020842c8a..e6cecd0ceb 100644
--- a/deal.II/include/deal.II/lac/constraint_matrix.h
+++ b/deal.II/include/deal.II/lac/constraint_matrix.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
@@ -150,58 +151,40 @@ public:
typedef types::global_dof_index size_type;
/**
- * An enum that describes what should
- * happen if the two ConstraintMatrix
- * objects involved in a call to the
- * merge() function happen to have
- * constraints on the same degrees of
- * freedom.
+ * An enum that describes what should happen if the two ConstraintMatrix
+ * objects involved in a call to the merge() function happen to have
+ * constraints on the same degrees of freedom.
*/
enum MergeConflictBehavior
{
/**
- * Throw an exception if the two
- * objects concerned have
- * conflicting constraints on the
- * same degree of freedom.
+ * Throw an exception if the two objects concerned have conflicting
+ * constraints on the same degree of freedom.
*/
no_conflicts_allowed,
/**
- * In an operation
- * cm1.merge(cm2), if
- * cm1 and
- * cm2 have
- * constraints on the same degree
- * of freedom, take the one from
- * cm1.
+ * In an operation cm1.merge(cm2), if cm1 and
+ * cm2 have constraints on the same degree of freedom, take
+ * the one from cm1.
*/
left_object_wins,
/**
- * In an operation
- * cm1.merge(cm2), if
- * cm1 and
- * cm2 have
- * constraints on the same degree
- * of freedom, take the one from
- * cm2.
+ * In an operation cm1.merge(cm2), if cm1 and
+ * cm2 have constraints on the same degree of freedom, take
+ * the one from cm2.
*/
right_object_wins
};
/**
- * Constructor. The supplied IndexSet
- * defines which indices might be
- * constrained inside this
- * ConstraintMatrix. In a calculation
- * with a
- * parallel::distributed::DoFHandler one
- * should use locally_relevant_dofs. The
- * IndexSet allows the ConstraintMatrix
- * to safe memory. Otherwise internal
- * data structures for all possible
- * indices will be created.
+ * Constructor. The supplied IndexSet defines which indices might be
+ * constrained inside this ConstraintMatrix. In a calculation with a
+ * parallel::distributed::DoFHandler one should use
+ * locally_relevant_dofs. The IndexSet allows the ConstraintMatrix to safe
+ * memory. Otherwise internal data structures for all possible indices will
+ * be created.
*/
ConstraintMatrix (const IndexSet &local_constraints = IndexSet());
@@ -211,25 +194,18 @@ public:
ConstraintMatrix (const ConstraintMatrix &constraint_matrix);
/**
- * Reinit the ConstraintMatrix object and
- * supply an IndexSet with lines that may
- * be constrained. This function is only
- * relevant in the distributed case to
- * supply a different IndexSet. Otherwise
- * this routine is equivalent to calling
- * clear(). See the constructor for
- * details.
+ * Reinit the ConstraintMatrix object and supply an IndexSet with lines that
+ * may be constrained. This function is only relevant in the distributed
+ * case to supply a different IndexSet. Otherwise this routine is equivalent
+ * to calling clear(). See the constructor for details.
*/
void reinit (const IndexSet &local_constraints = IndexSet());
/**
- * Determines if we can store a
- * constraint for the given @p
- * line_index. This routine only matters
- * in the distributed case and checks if
- * the IndexSet allows storage of this
- * line. Always returns true if not in
- * the distributed case.
+ * Determines if we can store a constraint for the given @p line_index. This
+ * routine only matters in the distributed case and checks if the IndexSet
+ * allows storage of this line. Always returns true if not in the
+ * distributed case.
*/
bool can_store_line (const size_type line_index) const;
@@ -242,39 +218,23 @@ public:
const IndexSet & get_local_lines() const;
/**
- * This function copies the content of @p
- * constraints_in with DoFs that are
- * element of the IndexSet @p
- * filter. Elements that are not present
- * in the IndexSet are ignored. All DoFs
- * will be transformed to local index
- * space of the filter, both the
- * constrained DoFs and the other DoFs
- * these entries are constrained to. The
- * local index space of the filter is a
- * contiguous numbering of all (global)
- * DoFs that are elements in the
- * filter.
- *
- * If, for example, the filter represents
- * the range [10,20), and the
- * constraint matrix @p constraints_in
- * includes the global indices
- * {7,13,14}, the indices
- * {3,4} are added to the
- * calling constraint matrix (since 13
- * and 14 are elements in the filter and
- * element 13 is the fourth element in
- * the index, and 14 is the fifth).
- *
- * This function provides an easy way to
- * create a ConstraintMatrix for certain
- * vector components in a vector-valued
- * problem from a full ConstraintMatrix,
- * i.e. extracting a diagonal subblock
- * from a larger ConstraintMatrix. The
- * block is specified by the IndexSet
- * argument.
+ * This function copies the content of @p constraints_in with DoFs that are
+ * element of the IndexSet @p filter. Elements that are not present in the
+ * IndexSet are ignored. All DoFs will be transformed to local index space
+ * of the filter, both the constrained DoFs and the other DoFs these entries
+ * are constrained to. The local index space of the filter is a contiguous
+ * numbering of all (global) DoFs that are elements in the filter.
+ *
+ * If, for example, the filter represents the range [10,20), and
+ * the constraint matrix @p constraints_in includes the global indices
+ * {7,13,14}, the indices {3,4} are added to the calling
+ * constraint matrix (since 13 and 14 are elements in the filter and element
+ * 13 is the fourth element in the index, and 14 is the fifth).
+ *
+ * This function provides an easy way to create a ConstraintMatrix for
+ * certain vector components in a vector-valued problem from a full
+ * ConstraintMatrix, i.e. extracting a diagonal subblock from a larger
+ * ConstraintMatrix. The block is specified by the IndexSet argument.
*/
void add_selected_constraints (const ConstraintMatrix &constraints_in,
const IndexSet &filter);
@@ -285,220 +245,147 @@ public:
*/
/**
- * Add a new line to the matrix. If the
- * line already exists, then the function
- * simply returns without doing anything.
+ * Add a new line to the matrix. If the line already exists, then the
+ * function simply returns without doing anything.
*/
void add_line (const size_type line);
/**
- * Call the first add_line() function for
- * every index i for which
- * lines[i] is true.
- *
- * This function essentially exists to
- * allow adding several constraints of
- * the form xi=0 all at once, where
- * the set of indices i for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * Call the first add_line() function for every index i for
+ * which lines[i] is true.
+ *
+ * This function essentially exists to allow adding several constraints of
+ * the form xi=0 all at once, where the set of indices
+ * i for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const std::vector &lines);
/**
- * Call the first add_line() function for
- * every index i that
+ * Call the first add_line() function for every index i that
* appears in the argument.
*
- * This function essentially exists to
- * allow adding several constraints of
- * the form xi=0 all at once, where
- * the set of indices i for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * This function essentially exists to allow adding several constraints of
+ * the form xi=0 all at once, where the set of indices
+ * i for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const std::set &lines);
/**
- * Call the first add_line() function for
- * every index i that
+ * Call the first add_line() function for every index i that
* appears in the argument.
*
- * This function essentially exists to
- * allow adding several constraints of
- * the form xi=0 all at once, where
- * the set of indices i for which these
- * constraints should be added are given
- * by the argument of this function. On
- * the other hand, just as if the
- * single-argument add_line() function
- * were called repeatedly, the
- * constraints can later be modified to
- * include linear dependencies using the
- * add_entry() function as well as
- * inhomogeneities using
+ * This function essentially exists to allow adding several constraints of
+ * the form xi=0 all at once, where the set of indices
+ * i for which these constraints should be added are given by the
+ * argument of this function. On the other hand, just as if the
+ * single-argument add_line() function were called repeatedly, the
+ * constraints can later be modified to include linear dependencies using
+ * the add_entry() function as well as inhomogeneities using
* set_inhomogeneity().
*/
void add_lines (const IndexSet &lines);
/**
- * Add an entry to a given
- * line. The list of lines is
- * searched from the back to the
- * front, so clever programming
- * would add a new line (which is
- * pushed to the back) and
- * immediately afterwards fill
- * the entries of that line. This
- * way, no expensive searching is
- * needed.
- *
- * If an entry with the same
- * indices as the one this
- * function call denotes already
- * exists, then this function
- * simply returns provided that
- * the value of the entry is the
- * same. Thus, it does no harm to
- * enter a constraint twice.
+ * Add an entry to a given line. The list of lines is searched from the back
+ * to the front, so clever programming would add a new line (which is pushed
+ * to the back) and immediately afterwards fill the entries of that
+ * line. This way, no expensive searching is needed.
+ *
+ * If an entry with the same indices as the one this function call denotes
+ * already exists, then this function simply returns provided that the value
+ * of the entry is the same. Thus, it does no harm to enter a constraint
+ * twice.
*/
void add_entry (const size_type line,
const size_type column,
const double value);
/**
- * Add a whole series of entries,
- * denoted by pairs of column indices
- * and values, to a line of
- * constraints. This function is
- * equivalent to calling the preceding
- * function several times, but is
- * faster.
+ * Add a whole series of entries, denoted by pairs of column indices and
+ * values, to a line of constraints. This function is equivalent to calling
+ * the preceding function several times, but is faster.
*/
void add_entries (const size_type line,
const std::vector > &col_val_pairs);
/**
- * Set an imhomogeneity to the
- * constraint line i, according
- * to the discussion in the general
- * class description.
+ * Set an imhomogeneity to the constraint line i, according to the
+ * discussion in the general class description.
*
- * @note the line needs to be added with
- * one of the add_line() calls first.
+ * @note the line needs to be added with one of the add_line() calls first.
*/
void set_inhomogeneity (const size_type line,
const double value);
/**
- * Close the filling of entries. Since
- * the lines of a matrix of this type
- * are usually filled in an arbitrary
- * order and since we do not want to
- * use associative constainers to store
- * the lines, we need to sort the lines
- * and within the lines the columns
- * before usage of the matrix. This is
- * done through this function.
- *
- * Also, zero entries are discarded,
- * since they are not needed.
- *
- * After closing, no more entries are
- * accepted. If the object was already
- * closed, then this function returns
- * immediately.
- *
- * This function also resolves chains
- * of constraints. For example, degree
- * of freedom 13 may be constrained to
- * u13=u3/2+u7/2 while degree of
- * freedom 7 is itself constrained as
- * u7=u2/2+u4/2. Then, the
- * resolution will be that
- * u13=u3/2+u2/4+u4/4. Note,
- * however, that cycles in this graph
- * of constraints are not allowed,
- * i.e. for example u4 may not be
- * constrained, directly or indirectly,
- * to u13 again.
+ * Close the filling of entries. Since the lines of a matrix of this type
+ * are usually filled in an arbitrary order and since we do not want to use
+ * associative constainers to store the lines, we need to sort the lines and
+ * within the lines the columns before usage of the matrix. This is done
+ * through this function.
+ *
+ * Also, zero entries are discarded, since they are not needed.
+ *
+ * After closing, no more entries are accepted. If the object was already
+ * closed, then this function returns immediately.
+ *
+ * This function also resolves chains of constraints. For example, degree of
+ * freedom 13 may be constrained to $u_{13} = \frac{u_3}{2} + \frac{u_7}{2}$
+ * while degree of freedom 7 is itself constrained as $u_{7} = \frac{u_2}{2}
+ * + \frac{u_4}{2}$. Then, the resolution will be that $u_{13} =
+ * \frac{u_3}{2} + \frac{u_2}{4} + \frac{u_4}{4}$. Note, however, that
+ * cycles in this graph of constraints are not allowed, i.e. for example
+ * $u_4$ may not be constrained, directly or indirectly, to $u_{13}$ again.
*/
void close ();
/**
- * Merge the constraints represented by
- * the object given as argument into
- * the constraints represented by this
- * object. Both objects may or may not
- * be closed (by having their function
- * close() called before). If this
- * object was closed before, then it
- * will be closed afterwards as
- * well. Note, however, that if the
- * other argument is closed, then
- * merging may be significantly faster.
- *
- * Using the default value of the second
- * arguments, the constraints in each of
- * the two objects (the old one
- * represented by this object and the
- * argument) may not refer to the same
- * degree of freedom, i.e. a degree of
- * freedom that is constrained in one
- * object may not be constrained in the
- * second. If this is nevertheless the
- * case, an exception is thrown. However,
- * this behavior can be changed by
- * providing a different value for the
- * second argument.
+ * Merge the constraints represented by the object given as argument into
+ * the constraints represented by this object. Both objects may or may not
+ * be closed (by having their function close() called before). If this
+ * object was closed before, then it will be closed afterwards as
+ * well. Note, however, that if the other argument is closed, then merging
+ * may be significantly faster.
+ *
+ * Using the default value of the second arguments, the constraints in each
+ * of the two objects (the old one represented by this object and the
+ * argument) may not refer to the same degree of freedom, i.e. a degree of
+ * freedom that is constrained in one object may not be constrained in the
+ * second. If this is nevertheless the case, an exception is
+ * thrown. However, this behavior can be changed by providing a different
+ * value for the second argument.
*/
void merge (const ConstraintMatrix &other_constraints,
const MergeConflictBehavior merge_conflict_behavior = no_conflicts_allowed);
/**
- * Shift all entries of this matrix
- * down @p offset rows and over @p
- * offset columns.
+ * Shift all entries of this matrix down @p offset rows and over @p offset
+ * columns.
*
- * This function is useful if you are
- * building block matrices, where all
- * blocks are built by the same
- * DoFHandler object, i.e. the matrix
- * size is larger than the number of
- * degrees of freedom. Since several
- * matrix rows and columns correspond
- * to the same degrees of freedom,
- * you'd generate several constraint
- * objects, then shift them, and
- * finally merge() them together
- * again.
+ * This function is useful if you are building block matrices, where all
+ * blocks are built by the same DoFHandler object, i.e. the matrix size is
+ * larger than the number of degrees of freedom. Since several matrix rows
+ * and columns correspond to the same degrees of freedom, you'd generate
+ * several constraint objects, then shift them, and finally merge() them
+ * together again.
*/
void shift (const size_type offset);
/**
- * Clear all entries of this
- * matrix. Reset the flag determining
- * whether new entries are accepted or
- * not.
+ * Clear all entries of this matrix. Reset the flag determining whether new
+ * entries are accepted or not.
*
- * This function may be called also on
- * objects which are empty or already
+ * This function may be called also on objects which are empty or already
* cleared.
*/
void clear ();
@@ -514,51 +401,37 @@ public:
*/
/**
- * Return number of constraints stored in
- * this matrix.
+ * Return number of constraints stored in this matrix.
*/
size_type n_constraints () const;
/**
- * Return whether the degree of freedom
- * with number @p index is a
+ * Return whether the degree of freedom with number @p index is a
* constrained one.
*
- * Note that if close() was called
- * before, then this function is
- * significantly faster, since then the
- * constrained degrees of freedom are
- * sorted and we can do a binary
- * search, while before close() was
- * called, we have to perform a linear
- * search through all entries.
+ * Note that if close() was called before, then this function is
+ * significantly faster, since then the constrained degrees of freedom are
+ * sorted and we can do a binary search, while before close() was called, we
+ * have to perform a linear search through all entries.
*/
bool is_constrained (const size_type index) const;
/**
- * Return whether the dof is
- * constrained, and whether it is
- * constrained to only one other degree
- * of freedom with weight one. The
- * function therefore returns whether
- * the degree of freedom would simply
- * be eliminated in favor of exactly
- * one other degree of freedom.
- *
- * The function returns @p false if
- * either the degree of freedom is not
- * constrained at all, or if it is
- * constrained to more than one other
- * degree of freedom, or if it is
- * constrained to only one degree of
- * freedom but with a weight different
- * from one.
+ * Return whether the dof is constrained, and whether it is constrained to
+ * only one other degree of freedom with weight one. The function therefore
+ * returns whether the degree of freedom would simply be eliminated in favor
+ * of exactly one other degree of freedom.
+ *
+ * The function returns @p false if either the degree of freedom is not
+ * constrained at all, or if it is constrained to more than one other degree
+ * of freedom, or if it is constrained to only one degree of freedom but
+ * with a weight different from one.
*/
bool is_identity_constrained (const size_type index) const;
/**
- * Return whether the two given degrees of freedom are linked by an
- * equality constraint that either constrains index1 to be so that
+ * Return whether the two given degrees of freedom are linked by an equality
+ * constraint that either constrains index1 to be so that
* index1=index2 or constrains index2 so that
* index2=index1.
*/
@@ -566,105 +439,78 @@ public:
const size_type index2) const;
/**
- * Return the maximum number of other
- * dofs that one dof is constrained
- * to. For example, in 2d a hanging
- * node is constrained only to its two
- * neighbors, so the returned value
- * would be 2. However, for higher
- * order elements and/or higher
- * dimensions, or other types of
- * constraints, this number is no more
- * obvious.
+ * Return the maximum number of other dofs that one dof is constrained
+ * to. For example, in 2d a hanging node is constrained only to its two
+ * neighbors, so the returned value would be 2. However, for higher order
+ * elements and/or higher dimensions, or other types of constraints, this
+ * number is no more obvious.
*
- * The name indicates that within the
- * system matrix, references to a
- * constrained node are indirected to
- * the nodes it is constrained to.
+ * The name indicates that within the system matrix, references to a
+ * constrained node are indirected to the nodes it is constrained to.
*/
size_type max_constraint_indirections () const;
/**
- * Returns true in case the
- * dof is constrained and there is a
- * non-trivial inhomogeneous valeus set
- * to the dof.
+ * Returns true in case the dof is constrained and there is a
+ * non-trivial inhomogeneous valeus set to the dof.
*/
bool is_inhomogeneously_constrained (const size_type index) const;
/**
- * Returns false if all
- * constraints in the ConstraintMatrix
- * are homogeneous ones, and
- * true if there is at least
- * one inhomogeneity.
+ * Returns false if all constraints in the ConstraintMatrix are
+ * homogeneous ones, and true if there is at least one
+ * inhomogeneity.
*/
bool has_inhomogeneities () const;
/**
- * Returns a pointer to the the vector of
- * entries if a line is constrained, and a
- * zero pointer in case the dof is not
- * constrained.
+ * Returns a pointer to the the vector of entries if a line is constrained,
+ * and a zero pointer in case the dof is not constrained.
*/
const std::vector > *
get_constraint_entries (const size_type line) const;
/**
- * Returns the value of the inhomogeneity
- * stored in the constrained dof @p
- * line. Unconstrained dofs also return a
- * zero value.
+ * Returns the value of the inhomogeneity stored in the constrained dof @p
+ * line. Unconstrained dofs also return a zero value.
*/
double get_inhomogeneity (const size_type line) const;
/**
- * Print the constraint lines. Mainly
- * for debugging purposes.
+ * Print the constraint lines. Mainly for debugging purposes.
*
- * This function writes out all entries
- * in the constraint matrix lines with
- * their value in the form row col
- * : value. Unconstrained lines
- * containing only one identity entry
- * are not stored in this object and
- * are not printed.
+ * This function writes out all entries in the constraint matrix lines with
+ * their value in the form row col : value. Unconstrained lines
+ * containing only one identity entry are not stored in this object and are
+ * not printed.
*/
void print (std::ostream &) const;
/**
- * Write the graph of constraints in
- * 'dot' format. 'dot' is a program
- * that can take a list of nodes and
- * produce a graphical representation
- * of the graph of constrained degrees
- * of freedom and the degrees of
- * freedom they are constrained to.
+ * Write the graph of constraints in 'dot' format. 'dot' is a program that
+ * can take a list of nodes and produce a graphical representation of the
+ * graph of constrained degrees of freedom and the degrees of freedom they
+ * are constrained to.
*
- * The output of this function can be
- * used as input to the 'dot' program
- * that can convert the graph into a
- * graphical representation in
- * postscript, png, xfig, and a number
- * of other formats.
+ * The output of this function can be used as input to the 'dot' program
+ * that can convert the graph into a graphical representation in postscript,
+ * png, xfig, and a number of other formats.
*
- * This function exists mostly for
- * debugging purposes.
+ * This function exists mostly for debugging purposes.
*/
void write_dot (std::ostream &) const;
/**
- * Determine an estimate for the memory
- * consumption (in bytes) of this
+ * Determine an estimate for the memory consumption (in bytes) of this
* object.
*/
std::size_t memory_consumption () const;
/**
* Add the constraint indices associated to the indices in the given vector.
- * After a call to this function, the indices vector contains the
- * initial elements and all the associated constrained indices. This
- * function sorts the elements and suppresses duplicates.
+ * After a call to this function, the indices vector contains the initial
+ * elements and all the associated constrained indices. This function sorts
+ * the elements and suppresses duplicates.
*/
void resolve_indices(std::vector &indices) const;
@@ -678,150 +524,100 @@ public:
*/
/**
- * Condense a given sparsity
- * pattern. This function assumes the
- * uncondensed matrix struct to be
- * compressed and the one to be filled
- * to be empty. The condensed structure
- * is compressed afterwards.
+ * Condense a given sparsity pattern. This function assumes the uncondensed
+ * matrix struct to be compressed and the one to be filled to be empty. The
+ * condensed structure is compressed afterwards.
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
- * @note The hanging nodes are
- * completely eliminated from the
- * linear system referring to
- * condensed. Therefore, the
- * dimension of condensed is
- * the dimension of
- * uncondensed minus the
- * number of constrained degrees of
- * freedom.
+ * @note The hanging nodes are completely eliminated from the linear system
+ * referring to condensed. Therefore, the dimension of
+ * condensed is the dimension of uncondensed minus the
+ * number of constrained degrees of freedom.
*/
void condense (const SparsityPattern &uncondensed,
SparsityPattern &condensed) const;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses the matrix struct
- * 'in-place'. It does not remove
- * nonzero entries from the matrix but
- * adds those needed for the process of
- * distribution of the constrained
- * degrees of freedom.
+ * This function does much the same as the above one, except that it
+ * condenses the matrix struct 'in-place'. It does not remove nonzero
+ * entries from the matrix but adds those needed for the process of
+ * distribution of the constrained degrees of freedom.
*
- * Since this function adds new nonzero
- * entries to the sparsity pattern, the
- * argument must not be
- * compressed. However the constraint
- * matrix must be closed. The matrix
- * struct is compressed at the end of
- * the function.
+ * Since this function adds new nonzero entries to the sparsity pattern, the
+ * argument must not be compressed. However the constraint matrix must be
+ * closed. The matrix struct is compressed at the end of the function.
*/
void condense (SparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square block sparsity
- * patterns.
+ * Same function as above, but condenses square block sparsity patterns.
*/
void condense (BlockSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*
- * Given the data structure used by
- * CompressedSparsityPattern, this
- * function becomes quadratic in the
- * number of degrees of freedom for
- * large problems and can dominate
- * setting up linear systems when
- * several hundred thousand or millions
- * of unknowns are involved and for
- * problems with many nonzero elements
- * per row (for example for
- * vector-valued problems or hp finite
- * elements). In this case, it is
- * advisable to use the
- * CompressedSetSparsityPattern class
- * instead, see for example @ref
- * step_27 "step-27", or to use the
- * CompressedSimpleSparsityPattern
- * class, see for example @ref step_31
- * "step-31".
+ * Given the data structure used by CompressedSparsityPattern, this function
+ * becomes quadratic in the number of degrees of freedom for large problems
+ * and can dominate setting up linear systems when several hundred thousand
+ * or millions of unknowns are involved and for problems with many nonzero
+ * elements per row (for example for vector-valued problems or hp finite
+ * elements). In this case, it is advisable to use the
+ * CompressedSetSparsityPattern class instead, see for example @ref step_27
+ * "step-27", or to use the CompressedSimpleSparsityPattern class, see for
+ * example @ref step_31 "step-31".
*/
void condense (CompressedSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses compressed sparsity
- * patterns, which are based on the
- * std::set container.
+ * Same function as above, but condenses compressed sparsity patterns, which
+ * are based on the std::set container.
*/
void condense (CompressedSetSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses compressed sparsity
- * patterns, which are based on the
- * ''simple'' aproach.
+ * Same function as above, but condenses compressed sparsity patterns, which
+ * are based on the ''simple'' aproach.
*/
void condense (CompressedSimpleSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*
- * Given the data structure used by
- * BlockCompressedSparsityPattern, this
- * function becomes quadratic in the
- * number of degrees of freedom for
- * large problems and can dominate
- * setting up linear systems when
- * several hundred thousand or millions
- * of unknowns are involved and for
- * problems with many nonzero elements
- * per row (for example for
- * vector-valued problems or hp finite
- * elements). In this case, it is
- * advisable to use the
- * BlockCompressedSetSparsityPattern
- * class instead, see for example @ref
- * step_27 "step-27" and @ref step_31
- * "step-31".
+ * Given the data structure used by BlockCompressedSparsityPattern, this
+ * function becomes quadratic in the number of degrees of freedom for large
+ * problems and can dominate setting up linear systems when several hundred
+ * thousand or millions of unknowns are involved and for problems with many
+ * nonzero elements per row (for example for vector-valued problems or hp
+ * finite elements). In this case, it is advisable to use the
+ * BlockCompressedSetSparsityPattern class instead, see for example @ref
+ * step_27 "step-27" and @ref step_31 "step-31".
*/
void condense (BlockCompressedSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*/
void condense (BlockCompressedSetSparsityPattern &sparsity) const;
/**
- * Same function as above, but
- * condenses square compressed sparsity
+ * Same function as above, but condenses square compressed sparsity
* patterns.
*/
void condense (BlockCompressedSimpleSparsityPattern &sparsity) const;
/**
- * Condense a given matrix. The
- * associated matrix struct should be
- * condensed and compressed. It is the
- * user's responsibility to guarantee
- * that all entries in the @p condensed
- * matrix be zero!
+ * Condense a given matrix. The associated matrix struct should be condensed
+ * and compressed. It is the user's responsibility to guarantee that all
+ * entries in the @p condensed matrix be zero!
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
@@ -832,42 +628,30 @@ public:
SparseMatrix &condensed) const DEAL_II_DEPRECATED;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses the matrix 'in-place'. See
- * the general documentation of this
+ * This function does much the same as the above one, except that it
+ * condenses the matrix 'in-place'. See the general documentation of this
* class for more detailed information.
*/
template
void condense (SparseMatrix &matrix) const;
/**
- * Same function as above, but
- * condenses square block sparse
- * matrices.
+ * Same function as above, but condenses square block sparse matrices.
*/
template
void condense (BlockSparseMatrix &matrix) const;
/**
- * Condense the given vector @p
- * uncondensed into @p condensed. It is
- * the user's responsibility to
- * guarantee that all entries of @p
- * condensed be zero. Note that this
- * function does not take any
- * inhomogeneity into account and
- * throws an exception in case there
- * are any inhomogeneities. Use
- * the function using both a matrix and
- * vector for that case.
- *
- * The @p VectorType may be a
- * Vector, Vector,
- * BlockVector<...>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface.
+ * Condense the given vector @p uncondensed into @p condensed. It is the
+ * user's responsibility to guarantee that all entries of @p condensed be
+ * zero. Note that this function does not take any inhomogeneity into
+ * account and throws an exception in case there are any
+ * inhomogeneities. Use the function using both a matrix and vector for that
+ * case.
+ *
+ * The @p VectorType may be a Vector, Vector,
+ * BlockVector<...>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
@@ -878,36 +662,25 @@ public:
VectorType &condensed) const DEAL_II_DEPRECATED;
/**
- * Condense the given vector
- * in-place. The @p VectorType may be a
- * Vector, Vector,
- * BlockVector<...>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface. Note that this function
- * does not take any inhomogeneity into
- * account and throws an exception in
- * case there are any
- * inhomogeneities. Use the function
- * using both a matrix and vector for
- * that case.
+ * Condense the given vector in-place. The @p VectorType may be a
+ * Vector, Vector, BlockVector<...>, a PETSc or
+ * Trilinos vector wrapper class, or any other type having the same
+ * interface. Note that this function does not take any inhomogeneity into
+ * account and throws an exception in case there are any
+ * inhomogeneities. Use the function using both a matrix and vector for that
+ * case.
*/
template
void condense (VectorType &vec) const;
/**
- * Condense a given matrix and a given
- * vector. The associated matrix struct
- * should be condensed and
- * compressed. It is the user's
- * responsibility to guarantee that all
- * entries in the @p condensed matrix
- * and vector be zero! This function is
- * the appropriate choice for applying
- * inhomogeneous constraints.
+ * Condense a given matrix and a given vector. The associated matrix struct
+ * should be condensed and compressed. It is the user's responsibility to
+ * guarantee that all entries in the @p condensed matrix and vector be zero!
+ * This function is the appropriate choice for applying inhomogeneous
+ * constraints.
*
- * The constraint matrix object must be
- * closed to call this function.
+ * The constraint matrix object must be closed to call this function.
*
* @deprecated The functions converting an uncondensed matrix into
* its condensed form are deprecated. Use the functions doing the
@@ -920,36 +693,27 @@ public:
VectorType &condensed_vector) const DEAL_II_DEPRECATED;
/**
- * This function does much the same as
- * the above one, except that it
- * condenses matrix and vector
- * 'in-place'. See the general
- * documentation of this class for more
- * detailed information.
+ * This function does much the same as the above one, except that it
+ * condenses matrix and vector 'in-place'. See the general documentation of
+ * this class for more detailed information.
*/
template
void condense (SparseMatrix &matrix,
VectorType &vector) const;
/**
- * Same function as above, but
- * condenses square block sparse
- * matrices and vectors.
+ * Same function as above, but condenses square block sparse matrices and
+ * vectors.
*/
template
void condense (BlockSparseMatrix &matrix,
BlockVectorType &vector) const;
/**
- * Sets the values of all constrained
- * DoFs in a vector to zero.
- * The @p VectorType may be a
- * Vector, Vector,
- * BlockVector<...>, a
- * PETSc or Trilinos vector
- * wrapper class, or any other
- * type having the same
- * interface.
+ * Sets the values of all constrained DoFs in a vector to zero. The @p
+ * VectorType may be a Vector, Vector,
+ * BlockVector<...>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*/
template
void set_zero (VectorType &vec) const;
@@ -964,59 +728,40 @@ public:
*/
/**
- * This function takes a vector of
- * local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_vector and @p
- * local_dof_indices have the same
- * number of elements, this function is
- * happy with whatever it is
- * given.
- *
- * In contrast to the similar function
- * in the DoFAccessor class, this
- * function also takes care of
- * constraints, i.e. if one of the
- * elements of @p local_dof_indices
- * belongs to a constrained node, then
- * rather than writing the
- * corresponding element of @p
- * local_vector into @p global_vector,
- * the element is distributed to the
- * entries in the global vector to
- * which this particular degree of
- * freedom is constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to the
- * global object, one saves the call to
- * the condense function after the
- * vectors and matrices are fully
- * assembled. On the other hand, by
- * consequence, the function does not
- * only write into the entries enumerated
- * by the @p local_dof_indices array, but
- * also (possibly) others as necessary.
- *
- * Note that this function will apply all
- * constraints as if they were
- * homogeneous. For correctly setting
- * inhomogeneous constraints, use the
- * similar function with a matrix
- * argument or the function with both
- * matrix and vector arguments.
- *
- * @note This function is not
- * thread-safe, so you will need to make
- * sure that only one process at a time
- * calls this function.
+ * This function takes a vector of local contributions (@p local_vector)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_vector and @p
+ * local_dof_indices have the same number of elements, this function is
+ * happy with whatever it is given.
+ *
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_vector into @p
+ * global_vector, the element is distributed to the entries in the global
+ * vector to which this particular degree of freedom is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. On the other hand, by
+ * consequence, the function does not only write into the entries enumerated
+ * by the @p local_dof_indices array, but also (possibly) others as
+ * necessary.
+ *
+ * Note that this function will apply all constraints as if they were
+ * homogeneous. For correctly setting inhomogeneous constraints, use the
+ * similar function with a matrix argument or the function with both matrix
+ * and vector arguments.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
void
@@ -1025,75 +770,47 @@ public:
OutVector &global_vector) const;
/**
- * This function takes a vector of
- * local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_vector and @p
- * local_dof_indices have the same
- * number of elements, this function is
- * happy with whatever it is
- * given.
- *
- * In contrast to the similar function in
- * the DoFAccessor class, this function
- * also takes care of constraints,
- * i.e. if one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p local_vector into @p global_vector,
- * the element is distributed to the
- * entries in the global vector to which
- * this particular degree of freedom is
- * constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to the
- * global object, one saves the call to
- * the condense function after the
- * vectors and matrices are fully
- * assembled. On the other hand, by
- * consequence, the function does not
- * only write into the entries enumerated
- * by the @p local_dof_indices array, but
- * also (possibly) others as
- * necessary. This includes writing into
- * diagonal elements of the matrix if the
- * corresponding degree of freedom is
- * constrained.
+ * This function takes a vector of local contributions (@p local_vector)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_vector and @p
+ * local_dof_indices have the same number of elements, this function is
+ * happy with whatever it is given.
*
- * The fourth argument
- * local_matrix is intended to
- * be used in case one wants to apply
- * inhomogeneous constraints on the
- * vector only. Such a situation could be
- * where one wants to assemble of a right
- * hand side vector on a problem with
- * inhomogeneous constraints, but the
- * global matrix has been assembled
- * previously. A typical example of this
- * is a time stepping algorithm where the
- * stiffness matrix is assembled once,
- * and the right hand side updated every
- * time step. Note that, however, the
- * entries in the columns of the local
- * matrix have to be exactly the same as
- * those that have been written into the
- * global matrix. Otherwise, this
- * function will not be able to correctly
- * handle inhomogeneities.
- *
- * @note This function is not
- * thread-safe, so you will need to make
- * sure that only one process at a time
- * calls this function.
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_vector into @p
+ * global_vector, the element is distributed to the entries in the global
+ * vector to which this particular degree of freedom is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. On the other hand, by
+ * consequence, the function does not only write into the entries enumerated
+ * by the @p local_dof_indices array, but also (possibly) others as
+ * necessary. This includes writing into diagonal elements of the matrix if
+ * the corresponding degree of freedom is constrained.
+ *
+ * The fourth argument local_matrix is intended to be used in case
+ * one wants to apply inhomogeneous constraints on the vector only. Such a
+ * situation could be where one wants to assemble of a right hand side
+ * vector on a problem with inhomogeneous constraints, but the global matrix
+ * has been assembled previously. A typical example of this is a time
+ * stepping algorithm where the stiffness matrix is assembled once, and the
+ * right hand side updated every time step. Note that, however, the entries
+ * in the columns of the local matrix have to be exactly the same as those
+ * that have been written into the global matrix. Otherwise, this function
+ * will not be able to correctly handle inhomogeneities.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
void
@@ -1103,8 +820,7 @@ public:
const FullMatrix &local_matrix) const;
/**
- * Enter a single value into a
- * result vector, obeying constraints.
+ * Enter a single value into a result vector, obeying constraints.
*/
template
void
@@ -1113,45 +829,32 @@ public:
VectorType &global_vector) const;
/**
- * This function takes a pointer to a
- * vector of local contributions (@p
- * local_vector) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global vector. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as the
- * entries in @p local_dof_indices
- * indicate reasonable global vector
- * entries, this function is happy with
- * whatever it is given.
- *
- * If one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p local_vector into @p
- * global_vector, the element is
- * distributed to the entries in the
- * global vector to which this
- * particular degree of freedom is
- * constrained.
- *
- * Thus, by using this function to
- * distribute local contributions to
- * the global object, one saves the
- * call to the condense function after
- * the vectors and matrices are fully
- * assembled. Note that this function
- * completely ignores inhomogeneous
- * constraints.
- *
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * This function takes a pointer to a vector of local contributions (@p
+ * local_vector) corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global vector. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as the entries in @p
+ * local_dof_indices indicate reasonable global vector entries, this
+ * function is happy with whatever it is given.
+ *
+ * If one of the elements of @p local_dof_indices belongs to a constrained
+ * node, then rather than writing the corresponding element of @p
+ * local_vector into @p global_vector, the element is distributed to the
+ * entries in the global vector to which this particular degree of freedom
+ * is constrained.
+ *
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled. Note that this function
+ * completely ignores inhomogeneous constraints.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global vector allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
@@ -1162,71 +865,45 @@ public:
VectorType &global_vector) const;
/**
- * This function takes a matrix of
- * local contributions (@p
- * local_matrix) corresponding to the
- * degrees of freedom indices given in
- * @p local_dof_indices and distributes
- * them to the global matrix. In most
- * cases, these local contributions
- * will be the result of an integration
- * over a cell or face of a
- * cell. However, as long as @p
- * local_matrix and @p
- * local_dof_indices have the same
- * number of elements, this function is
+ * This function takes a matrix of local contributions (@p local_matrix)
+ * corresponding to the degrees of freedom indices given in @p
+ * local_dof_indices and distributes them to the global matrix. In most
+ * cases, these local contributions will be the result of an integration
+ * over a cell or face of a cell. However, as long as @p local_matrix and @p
+ * local_dof_indices have the same number of elements, this function is
* happy with whatever it is given.
*
- * In contrast to the similar function
- * in the DoFAccessor class, this
- * function also takes care of
- * constraints, i.e. if one of the
- * elements of @p local_dof_indices
- * belongs to a constrained node, then
- * rather than writing the
- * corresponding element of @p
- * local_matrix into @p global_matrix,
- * the element is distributed to the
- * entries in the global matrix to
- * which this particular degree of
- * freedom is constrained.
- *
- * With this scheme, we never write
- * into rows or columns of constrained
- * degrees of freedom. In order to make
- * sure that the resulting matrix can
- * still be inverted, we need to do
- * something with the diagonal elements
- * corresponding to constrained
- * nodes. Thus, if a degree of freedom
- * in @p local_dof_indices is
- * constrained, we distribute the
- * corresponding entries in the matrix,
- * but also add the absolute value of
- * the diagonal entry of the local
- * matrix to the corresponding entry in
- * the global matrix. Since the exact
- * value of the diagonal element is not
- * important (the value of the
- * respective degree of freedom will be
- * overwritten by the distribute() call
- * later on anyway), this guarantees
- * that the diagonal entry is always
- * non-zero, positive, and of the same
- * order of magnitude as the other
+ * In contrast to the similar function in the DoFAccessor class, this
+ * function also takes care of constraints, i.e. if one of the elements of
+ * @p local_dof_indices belongs to a constrained node, then rather than
+ * writing the corresponding element of @p local_matrix into @p
+ * global_matrix, the element is distributed to the entries in the global
+ * matrix to which this particular degree of freedom is constrained.
+ *
+ * With this scheme, we never write into rows or columns of constrained
+ * degrees of freedom. In order to make sure that the resulting matrix can
+ * still be inverted, we need to do something with the diagonal elements
+ * corresponding to constrained nodes. Thus, if a degree of freedom in @p
+ * local_dof_indices is constrained, we distribute the corresponding entries
+ * in the matrix, but also add the absolute value of the diagonal entry of
+ * the local matrix to the corresponding entry in the global matrix. Since
+ * the exact value of the diagonal element is not important (the value of
+ * the respective degree of freedom will be overwritten by the distribute()
+ * call later on anyway), this guarantees that the diagonal entry is always
+ * non-zero, positive, and of the same order of magnitude as the other
* entries of the matrix.
*
- * Thus, by using this function to
- * distribute local contributions to
- * the global object, one saves the
- * call to the condense function after
- * the vectors and matrices are fully
- * assembled.
+ * Thus, by using this function to distribute local contributions to the
+ * global object, one saves the call to the condense function after the
+ * vectors and matrices are fully assembled.
*
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global matrix allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
void
@@ -1235,9 +912,7 @@ public:
MatrixType &global_matrix) const;
/**
- * Does the same as the function
- * above but can treat non
- * quadratic matrices.
+ * Does the same as the function above but can treat non quadratic matrices.
*/
template
void
@@ -1247,22 +922,19 @@ public:
MatrixType &global_matrix) const;
/**
- * This function simultaneously
- * writes elements into matrix
- * and vector, according to the
- * constraints specified by the
- * calling ConstraintMatrix. This
- * function can correctly handle
- * inhomogeneous constraints as
- * well. For the parameter
- * use_inhomogeneities_for_rhs
- * see the documentation in @ref
- * constraints module.
+ * This function simultaneously writes elements into matrix and vector,
+ * according to the constraints specified by the calling
+ * ConstraintMatrix. This function can correctly handle inhomogeneous
+ * constraints as well. For the parameter use_inhomogeneities_for_rhs see
+ * the documentation in @ref constraints module.
*
- * @note This function is not
- * thread-safe, so you will need to
- * make sure that only one process at a
- * time calls this function.
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global matrix and vector allow
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
void
@@ -1274,97 +946,67 @@ public:
bool use_inhomogeneities_for_rhs = false) const;
/**
- * Do a similar operation as the
- * distribute_local_to_global() function
- * that distributes writing entries into
- * a matrix for constrained degrees of
- * freedom, except that here we don't
- * write into a matrix but only allocate
+ * Do a similar operation as the distribute_local_to_global() function that
+ * distributes writing entries into a matrix for constrained degrees of
+ * freedom, except that here we don't write into a matrix but only allocate
* sparsity pattern entries.
*
- * As explained in the
- * @ref hp_paper "hp paper"
- * and in step-27,
- * first allocating a sparsity pattern
- * and later coming back and allocating
- * additional entries for those matrix
- * entries that will be written to due to
- * the elimination of constrained degrees
- * of freedom (using
- * ConstraintMatrix::condense() ), can be
- * a very expensive procedure. It is
- * cheaper to allocate these entries
- * right away without having to do a
- * second pass over the sparsity pattern
- * object. This function does exactly
+ * As explained in the @ref hp_paper "hp paper" and in step-27, first
+ * allocating a sparsity pattern and later coming back and allocating
+ * additional entries for those matrix entries that will be written to due
+ * to the elimination of constrained degrees of freedom (using
+ * ConstraintMatrix::condense() ), can be a very expensive procedure. It is
+ * cheaper to allocate these entries right away without having to do a
+ * second pass over the sparsity pattern object. This function does exactly
* that.
*
- * Because the function only allocates
- * entries in a sparsity pattern, all it
- * needs to know are the degrees of
- * freedom that couple to each
- * other. Unlike the previous function,
- * no actual values are written, so the
- * second input argument is not necessary
- * here.
- *
- * The third argument to this function,
- * keep_constrained_entries determines
- * whether the function shall allocate
- * entries in the sparsity pattern at
- * all for entries that will later be
- * set to zero upon condensation of the
- * matrix. These entries are necessary
- * if the matrix is built
- * unconstrained, and only later
- * condensed. They are not necessary if
- * the matrix is built using the
- * distribute_local_to_global()
- * function of this class which
- * distributes entries right away when
- * copying a local matrix into a global
- * object. The default of this argument
- * is true, meaning to allocate the few
- * entries that may later be set to
- * zero.
- *
- * By default, the function adds
- * entries for all pairs of indices
- * given in the first argument to the
- * sparsity pattern (unless
- * keep_constrained_entries is
- * false). However, sometimes one would
- * like to only add a subset of all of
- * these pairs. In that case, the last
- * argument can be used which specifies
- * a boolean mask which of the pairs of
- * indices should be considered. If the
- * mask is false for a pair of indices,
- * then no entry will be added to the
- * sparsity pattern for this pair,
- * irrespective of whether one or both
- * of the indices correspond to
- * constrained degrees of freedom.
- *
- * This function is not typically called
- * from user code, but is used in the
- * DoFTools::make_sparsity_pattern()
- * function when passed a constraint
+ * Because the function only allocates entries in a sparsity pattern, all it
+ * needs to know are the degrees of freedom that couple to each
+ * other. Unlike the previous function, no actual values are written, so the
+ * second input argument is not necessary here.
+ *
+ * The third argument to this function, keep_constrained_entries determines
+ * whether the function shall allocate entries in the sparsity pattern at
+ * all for entries that will later be set to zero upon condensation of the
+ * matrix. These entries are necessary if the matrix is built unconstrained,
+ * and only later condensed. They are not necessary if the matrix is built
+ * using the distribute_local_to_global() function of this class which
+ * distributes entries right away when copying a local matrix into a global
+ * object. The default of this argument is true, meaning to allocate the few
+ * entries that may later be set to zero.
+ *
+ * By default, the function adds entries for all pairs of indices given in
+ * the first argument to the sparsity pattern (unless
+ * keep_constrained_entries is false). However, sometimes one would like to
+ * only add a subset of all of these pairs. In that case, the last argument
+ * can be used which specifies a boolean mask which of the pairs of indices
+ * should be considered. If the mask is false for a pair of indices, then no
+ * entry will be added to the sparsity pattern for this pair, irrespective
+ * of whether one or both of the indices correspond to constrained degrees
+ * of freedom.
+ *
+ * This function is not typically called from user code, but is used in the
+ * DoFTools::make_sparsity_pattern() function when passed a constraint
* matrix object.
+ *
+ * @note This function in itself is thread-safe, i.e., it works properly
+ * also when several threads call it simultaneously. However, the function
+ * call is only thread-safe if the underlying global sparsity pattern allows
+ * for simultaneous access and the access is not to rows with the same
+ * global index at the same time. This needs to be made sure from the
+ * caller's site. There is no locking mechanism inside this method to
+ * prevent data races.
*/
template
void
add_entries_local_to_global (const std::vector &local_dof_indices,
SparsityType &sparsity_pattern,
const bool keep_constrained_entries = true,
- const Table<2,bool> &dof_mask = default_empty_table) const;
+ const Table<2,bool> &dof_mask = default_empty_table) const;
/**
- * Similar to the other function,
- * but for non-quadratic sparsity
- * patterns.
+ * Similar to the other function, but for non-quadratic sparsity patterns.
*/
-
template
void
add_entries_local_to_global (const std::vector &row_indices,
@@ -1374,38 +1016,23 @@ public:
const Table<2,bool> &dof_mask = default_empty_table) const;
/**
- * This function imports values from a
- * global vector (@p global_vector) by
- * applying the constraints to a vector
- * of local values, expressed in
- * iterator format. In most cases, the
- * local values will be identified by
- * the local dof values on a
- * cell. However, as long as the
- * entries in @p local_dof_indices
- * indicate reasonable global vector
- * entries, this function is happy with
- * whatever it is given.
- *
- * If one of the elements of @p
- * local_dof_indices belongs to a
- * constrained node, then rather than
- * writing the corresponding element of
- * @p global_vector into @p
- * local_vector, the constraints are
- * resolved as the respective
- * distribute function does, i.e., the
- * local entry is constructed from the
- * global entries to which this
- * particular degree of freedom is
+ * This function imports values from a global vector (@p global_vector) by
+ * applying the constraints to a vector of local values, expressed in
+ * iterator format. In most cases, the local values will be identified by
+ * the local dof values on a cell. However, as long as the entries in @p
+ * local_dof_indices indicate reasonable global vector entries, this
+ * function is happy with whatever it is given.
+ *
+ * If one of the elements of @p local_dof_indices belongs to a constrained
+ * node, then rather than writing the corresponding element of @p
+ * global_vector into @p local_vector, the constraints are resolved as the
+ * respective distribute function does, i.e., the local entry is constructed
+ * from the global entries to which this particular degree of freedom is
* constrained.
*
- * In contrast to the similar function
- * get_dof_values in the DoFAccessor
- * class, this function does not need
- * the constrained values to be
- * correctly set (i.e., distribute to
- * be called).
+ * In contrast to the similar function get_dof_values in the DoFAccessor
+ * class, this function does not need the constrained values to be correctly
+ * set (i.e., distribute to be called).
*/
template
@@ -1425,41 +1052,29 @@ public:
*/
/**
- * Re-distribute the elements of the
- * vector @p condensed to @p
- * uncondensed. It is the user's
- * responsibility to guarantee that all
+ * Re-distribute the elements of the vector @p condensed to @p
+ * uncondensed. It is the user's responsibility to guarantee that all
* entries of @p uncondensed be zero!
*
- * This function undoes the action of
- * @p condense somehow, but it should
- * be noted that it is not the inverse
- * of @p condense.
+ * This function undoes the action of @p condense somehow, but it should be
+ * noted that it is not the inverse of @p condense.
*
- * The @p VectorType may be a
- * Vector, Vector,
- * BlockVector<...>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
- * interface.
+ * The @p VectorType may be a Vector, Vector,
+ * BlockVector<...>, a PETSc or Trilinos vector wrapper class, or
+ * any other type having the same interface.
*/
template
void distribute (const VectorType &condensed,
VectorType &uncondensed) const;
/**
- * Re-distribute the elements of the
- * vector in-place. The @p VectorType
- * may be a Vector,
- * Vector,
- * BlockVector<...>, a PETSc
- * or Trilinos vector wrapper class, or
- * any other type having the same
+ * Re-distribute the elements of the vector in-place. The @p VectorType may
+ * be a Vector, Vector, BlockVector<...>, a PETSc or
+ * Trilinos vector wrapper class, or any other type having the same
* interface.
*
- * Note that if called with a
- * TrilinosWrappers::MPI::Vector it may
- * not contain ghost elements.
+ * Note that if called with a TrilinosWrappers::MPI::Vector it may not
+ * contain ghost elements.
*/
template
void distribute (VectorType &vec) const;
@@ -1563,35 +1178,27 @@ public:
private:
/**
- * This class represents one line of a
- * constraint matrix.
+ * This class represents one line of a constraint matrix.
*/
struct ConstraintLine
{
/**
- * A data type in which we store the list
- * of entries that make up the homogenous
- * part of a constraint.
+ * A data type in which we store the list of entries that make up the
+ * homogenous part of a constraint.
*/
typedef std::vector > Entries;
/**
- * Number of this line. Since only
- * very few lines are stored, we
- * can not assume a specific order
- * and have to store the line
- * number explicitly.
+ * Number of this line. Since only very few lines are stored, we can not
+ * assume a specific order and have to store the line number explicitly.
*/
size_type line;
/**
- * Row numbers and values of the
- * entries in this line.
+ * Row numbers and values of the entries in this line.
*
- * For the reason why we use a
- * vector instead of a map and the
- * consequences thereof, the same
- * applies as what is said for
+ * For the reason why we use a vector instead of a map and the
+ * consequences thereof, the same applies as what is said for
* ConstraintMatrix::lines.
*/
Entries entries;
@@ -1602,159 +1209,177 @@ private:
double inhomogeneity;
/**
- * This operator is a bit weird and
- * unintuitive: it compares the
- * line numbers of two lines. We
- * need this to sort the lines; in
- * fact we could do this using a
- * comparison predicate. However,
- * this way, it is easier, albeit
- * unintuitive since two lines
- * really have no god-given order
+ * This operator is a bit weird and unintuitive: it compares the line
+ * numbers of two lines. We need this to sort the lines; in fact we could
+ * do this using a comparison predicate. However, this way, it is easier,
+ * albeit unintuitive since two lines really have no god-given order
* relation.
*/
bool operator < (const ConstraintLine &) const;
/**
- * This operator is likewise weird:
- * it checks whether the line
- * indices of the two operands are
- * equal, irrespective of the fact
- * that the contents of the line
- * may be different.
+ * This operator is likewise weird: it checks whether the line indices of
+ * the two operands are equal, irrespective of the fact that the contents
+ * of the line may be different.
*/
bool operator == (const ConstraintLine &) const;
/**
- * Determine an estimate for the
- * memory consumption (in bytes) of
- * this object.
+ * Determine an estimate for the memory consumption (in bytes) of this
+ * object.
*/
std::size_t memory_consumption () const;
};
/**
- * Store the lines of the matrix.
- * Entries are usually appended in an
- * arbitrary order and insertion into a
- * vector is done best at the end, so
- * the order is unspecified after all
- * entries are inserted. Sorting of the
- * entries takes place when calling the
- * close() function.
+ * Store the lines of the matrix. Entries are usually appended in an
+ * arbitrary order and insertion into a vector is done best at the end, so
+ * the order is unspecified after all entries are inserted. Sorting of the
+ * entries takes place when calling the close() function.
*
- * We could, instead of using a vector,
- * use an associative array, like a map
- * to store the lines. This, however,
- * would mean a much more fractioned
- * heap since it allocates many small
- * objects, and would additionally make
- * usage of this matrix much slower.
+ * We could, instead of using a vector, use an associative array, like a map
+ * to store the lines. This, however, would mean a much more fractioned heap
+ * since it allocates many small objects, and would additionally make usage
+ * of this matrix much slower.
*/
std::vector lines;
/**
- * A list of size_type that
- * contains the position of the
- * ConstraintLine of a constrained degree
- * of freedom, or
- * numbers::invalid_size_type if the
- * degree of freedom is not
- * constrained. The
- * numbers::invalid_size_type
- * return value returns thus whether
- * there is a constraint line for a given
- * degree of freedom index. Note that
- * this class has no notion of how many
- * degrees of freedom there really are,
- * so if we check whether there is a
- * constraint line for a given degree of
- * freedom, then this vector may actually
- * be shorter than the index of the DoF
- * we check for.
- *
- * This field exists since when adding a
- * new constraint line we have to figure
- * out whether it already
- * exists. Previously, we would simply
- * walk the unsorted list of constraint
- * lines until we either hit the end or
- * found it. This algorithm is O(N) if N
- * is the number of constraints, which
- * makes it O(N^2) when inserting all
- * constraints. For large problems with
- * many constraints, this could easily
- * take 5-10 per cent of the total run
- * time. With this field, we can save
- * this time since we find any constraint
- * in O(1) time or get to know that it a
- * certain degree of freedom is not
+ * A list of size_type that contains the position of the ConstraintLine of a
+ * constrained degree of freedom, or numbers::invalid_size_type if the
+ * degree of freedom is not constrained. The numbers::invalid_size_type
+ * return value returns thus whether there is a constraint line for a given
+ * degree of freedom index. Note that this class has no notion of how many
+ * degrees of freedom there really are, so if we check whether there is a
+ * constraint line for a given degree of freedom, then this vector may
+ * actually be shorter than the index of the DoF we check for.
+ *
+ * This field exists since when adding a new constraint line we have to
+ * figure out whether it already exists. Previously, we would simply walk
+ * the unsorted list of constraint lines until we either hit the end or
+ * found it. This algorithm is O(N) if N is the number of constraints, which
+ * makes it O(N^2) when inserting all constraints. For large problems with
+ * many constraints, this could easily take 5-10 per cent of the total run
+ * time. With this field, we can save this time since we find any constraint
+ * in O(1) time or get to know that it a certain degree of freedom is not
* constrained.
*
- * To make things worse, traversing the
- * list of existing constraints requires
- * reads from many different places in
- * memory. Thus, in large 3d
- * applications, the add_line() function
- * showed up very prominently in the
- * overall compute time, mainly because
- * it generated a lot of cache
- * misses. This should also be fixed by
- * using the O(1) algorithm to access the
- * fields of this array.
- *
- * The field is useful in a number of
- * other contexts as well, e.g. when one
- * needs random access to the constraints
- * as in all the functions that apply
- * constraints on the fly while add cell
- * contributions into vectors and
+ * To make things worse, traversing the list of existing constraints
+ * requires reads from many different places in memory. Thus, in large 3d
+ * applications, the add_line() function showed up very prominently in the
+ * overall compute time, mainly because it generated a lot of cache
+ * misses. This should also be fixed by using the O(1) algorithm to access
+ * the fields of this array.
+ *
+ * The field is useful in a number of other contexts as well, e.g. when one
+ * needs random access to the constraints as in all the functions that apply
+ * constraints on the fly while add cell contributions into vectors and
* matrices.
*/
std::vector lines_cache;
/**
- * This IndexSet is used to limit the
- * lines to save in the ContraintMatrix
- * to a subset. This is necessary,
- * because the lines_cache vector would
- * become too big in a distributed
- * calculation.
+ * This IndexSet is used to limit the lines to save in the ConstraintMatrix
+ * to a subset. This is necessary, because the lines_cache vector would
+ * become too big in a distributed calculation.
*/
IndexSet local_lines;
/**
- * Store whether the arrays are sorted.
- * If so, no new entries can be added.
+ * Store whether the arrays are sorted. If so, no new entries can be added.
*/
bool sorted;
/**
- * Internal function to calculate the
- * index of line @p line in the vector
+ * Scratch data that is used during calls to distribute_local_to_global and
+ * add_entries_local_to_global. In order to avoid frequent memory
+ * allocation, we keep the data alive from one call to the next.
+ */
+ struct ScratchData
+ {
+ /**
+ * Constructor, does nothing.
+ */
+ ScratchData () :
+ in_use (false)
+ {}
+
+ /**
+ * Copy constructor, does nothing
+ */
+ ScratchData (const ScratchData &) :
+ in_use (false)
+ {}
+
+ /**
+ * Stores whether the data is currently in use.
+ */
+ bool in_use;
+
+ /**
+ * Temporary array for column indices
+ */
+ std::vector columns;
+
+ /**
+ * Temporary array for column values
+ */
+ std::vector values;
+
+ /**
+ * Temporary array for block start indices
+ */
+ std::vector block_starts;
+
+ /**
+ * Temporary array for vector indices
+ */
+ std::vector vector_indices;
+
+ /**
+ * Data array for reorder row/column indices. Use a shared ptr to
+ * global_rows to avoid defining in the .h file
+ */
+ std_cxx1x::shared_ptr global_rows;
+
+ /**
+ * Data array for reorder row/column indices. Use a shared ptr to
+ * global_rows to avoid defining in the .h file
+ */
+ std_cxx1x::shared_ptr global_columns;
+ };
+
+ /**
+ * Here comes the actual data structure for the scratch data. It is made
+ * mutable since it is modified in a const function. Since only one thread
+ * can access it at a time, no conflicting access can occur. For this to be
+ * valid, we need to make sure that no call within
+ * distribute_local_to_global is made that by itself can spawn
+ * tasks. Otherwise, we might end up in a situation where several threads
+ * fight for the data.
+ */
+ mutable Threads::ThreadLocalStorage scratch_data;
+
+ /**
+ * Internal function to calculate the index of line @p line in the vector
* lines_cache using local_lines.
*/
size_type calculate_line_index (const size_type line) const;
/**
- * Return @p true if the weight of an
- * entry (the second element of the
- * pair) equals zero. This function is
- * used to delete entries with zero
- * weight.
+ * Return @p true if the weight of an entry (the second element of the pair)
+ * equals zero. This function is used to delete entries with zero weight.
*/
static bool check_zero_weight (const std::pair &p);
/**
- * Dummy table that serves as default
- * argument for function
+ * Dummy table that serves as default argument for function
* add_entries_local_to_global().
*/
static const Table<2,bool> default_empty_table;
/**
- * This function actually implements
- * the local_to_global function for
+ * This function actually implements the local_to_global function for
* standard (non-block) matrices.
*/
template
@@ -1768,9 +1393,8 @@ private:
internal::bool2type) const;
/**
- * This function actually implements
- * the local_to_global function for
- * block matrices.
+ * This function actually implements the local_to_global function for block
+ * matrices.
*/
template
void
@@ -1783,8 +1407,7 @@ private:
internal::bool2type) const;
/**
- * This function actually implements
- * the local_to_global function for
+ * This function actually implements the local_to_global function for
* standard (non-block) sparsity types.
*/
template
@@ -1796,9 +1419,8 @@ private:
internal::bool2type) const;
/**
- * This function actually implements
- * the local_to_global function for
- * block sparsity types.
+ * This function actually implements the local_to_global function for block
+ * sparsity types.
*/
template
void
@@ -1809,27 +1431,21 @@ private:
internal::bool2type) const;
/**
- * Internal helper function for
- * distribute_local_to_global function.
+ * Internal helper function for distribute_local_to_global function.
*
- * Creates a list of affected global rows
- * for distribution, including the local
- * rows where the entries come from. The
- * list is sorted according to the global
- * row indices.
+ * Creates a list of affected global rows for distribution, including the
+ * local rows where the entries come from. The list is sorted according to
+ * the global row indices.
*/
void
make_sorted_row_list (const std::vector &local_dof_indices,
internals::GlobalRowsFromLocal &global_rows) const;
/**
- * Internal helper function for
- * add_entries_local_to_global function.
+ * Internal helper function for add_entries_local_to_global function.
*
- * Creates a list of affected rows for
- * distribution without any additional
- * information, otherwise similar to the
- * other make_sorted_row_list()
+ * Creates a list of affected rows for distribution without any additional
+ * information, otherwise similar to the other make_sorted_row_list()
* function.
*/
void
@@ -1837,8 +1453,7 @@ private:
std::vector &active_dofs) const;
/**
- * Internal helper function for
- * distribute_local_to_global function.
+ * Internal helper function for distribute_local_to_global function.
*/
double
resolve_vector_entry (const size_type i,
@@ -1857,7 +1472,8 @@ ConstraintMatrix::ConstraintMatrix (const IndexSet &local_constraints)
:
lines (),
local_lines (local_constraints),
- sorted (false)
+ sorted (false),
+ scratch_data (ScratchData())
{
// make sure the IndexSet is compressed. Otherwise this can lead to crashes
// that are hard to find (only happen in release mode).
@@ -1874,7 +1490,8 @@ ConstraintMatrix::ConstraintMatrix (const ConstraintMatrix &constraint_matrix)
lines (constraint_matrix.lines),
lines_cache (constraint_matrix.lines_cache),
local_lines (constraint_matrix.local_lines),
- sorted (constraint_matrix.sorted)
+ sorted (constraint_matrix.sorted),
+ scratch_data (ScratchData())
{}
@@ -1884,34 +1501,25 @@ ConstraintMatrix::add_line (const size_type line)
{
Assert (sorted==false, ExcMatrixIsClosed());
- // the following can happen when we
- // compute with distributed meshes
- // and dof handlers and we
- // constrain a degree of freedom
- // whose number we don't have
- // locally. if we don't abort here
- // the program will try to allocate
- // several terabytes of memory to
- // resize the various arrays below
- // :-)
+ // the following can happen when we compute with distributed meshes and dof
+ // handlers and we constrain a degree of freedom whose number we don't have
+ // locally. if we don't abort here the program will try to allocate several
+ // terabytes of memory to resize the various arrays below :-)
Assert (line != numbers::invalid_size_type,
ExcInternalError());
const size_type line_index = calculate_line_index (line);
- // check whether line already exists; it
- // may, in which case we can just quit
+ // check whether line already exists; it may, in which case we can just quit
if (is_constrained(line))
return;
- // if necessary enlarge vector of
- // existing entries for cache
+ // if necessary enlarge vector of existing entries for cache
if (line_index >= lines_cache.size())
lines_cache.resize (std::max(2*static_cast(lines_cache.size()),
line_index+1),
numbers::invalid_size_type);
- // push a new line to the end of the
- // list
+ // push a new line to the end of the list
lines.push_back (ConstraintLine());
lines.back().line = line;
lines.back().inhomogeneity = 0.;
@@ -1930,14 +1538,11 @@ ConstraintMatrix::add_entry (const size_type line,
Assert (line != column,
ExcMessage ("Can't constrain a degree of freedom to itself"));
- // if in debug mode, check whether an
- // entry for this column already
- // exists and if it's the same as
- // the one entered at present
+ // if in debug mode, check whether an entry for this column already exists
+ // and if it's the same as the one entered at present
//
- // in any case: exit the function if an
- // entry for this column already exists,
- // since we don't want to enter it twice
+ // in any case: exit the function if an entry for this column already
+ // exists, since we don't want to enter it twice
Assert (lines_cache[calculate_line_index(line)] != numbers::invalid_size_type,
ExcInternalError());
ConstraintLine *line_ptr = &lines[lines_cache[calculate_line_index(line)]];
@@ -1998,8 +1603,7 @@ inline
bool
ConstraintMatrix::is_inhomogeneously_constrained (const size_type index) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(index);
if (line_index >= lines_cache.size() ||
@@ -2018,8 +1622,7 @@ inline
const std::vector > *
ConstraintMatrix::get_constraint_entries (const size_type line) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(line);
if (line_index >= lines_cache.size() ||
@@ -2035,8 +1638,7 @@ inline
double
ConstraintMatrix::get_inhomogeneity (const size_type line) const
{
- // check whether the entry is
- // constrained. could use is_constrained, but
+ // check whether the entry is constrained. could use is_constrained, but
// that means computing the line index twice
const size_type line_index = calculate_line_index(line);
if (line_index >= lines_cache.size() ||
@@ -2182,8 +1784,7 @@ distribute_local_to_global (const FullMatrix &local_matrix,
const std::vector &local_dof_indices,
MatrixType &global_matrix) const
{
- // create a dummy and hand on to the
- // function actually implementing this
+ // create a dummy and hand on to the function actually implementing this
// feature in the cm.templates.h file.
Vector dummy(0);
distribute_local_to_global (local_matrix, dummy, local_dof_indices,
@@ -2204,10 +1805,8 @@ distribute_local_to_global (const FullMatrix &local_matrix,
VectorType &global_vector,
bool use_inhomogeneities_for_rhs) const
{
- // enter the internal function with the
- // respective block information set, the
- // actual implementation follows in the
- // cm.templates.h file.
+ // enter the internal function with the respective block information set,
+ // the actual implementation follows in the cm.templates.h file.
distribute_local_to_global (local_matrix, local_vector, local_dof_indices,
global_matrix, global_vector, use_inhomogeneities_for_rhs,
internal::bool2type::value>());
@@ -2224,10 +1823,8 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
const bool keep_constrained_entries,
const Table<2,bool> &dof_mask) const
{
- // enter the internal function with the
- // respective block information set, the
- // actual implementation follows in the
- // cm.templates.h file.
+ // enter the internal function with the respective block information set,
+ // the actual implementation follows in the cm.templates.h file.
add_entries_local_to_global (local_dof_indices, sparsity_pattern,
keep_constrained_entries, dof_mask,
internal::bool2type::value>());
diff --git a/deal.II/include/deal.II/lac/constraint_matrix.templates.h b/deal.II/include/deal.II/lac/constraint_matrix.templates.h
index 4a1ce1888c..d2e4dce533 100644
--- a/deal.II/include/deal.II/lac/constraint_matrix.templates.h
+++ b/deal.II/include/deal.II/lac/constraint_matrix.templates.h
@@ -1197,39 +1197,26 @@ ConstraintMatrix::distribute (VectorType &vec) const
-// Some helper definitions for the
-// local_to_global functions.
+// Some helper definitions for the local_to_global functions.
namespace internals
{
typedef types::global_dof_index size_type;
- // this struct contains all the information
- // we need to store about each of the
- // global entries (global_row): are they
- // obtained directly by some local entry
- // (local_row) or some constraints
- // (constraint_position). This is not
- // directly used in the user code, but
- // accessed via the
- // GlobalRowsFromLocal.
+ // this struct contains all the information we need to store about each of
+ // the global entries (global_row): are they obtained directly by some local
+ // entry (local_row) or some constraints (constraint_position). This is not
+ // directly used in the user code, but accessed via the GlobalRowsFromLocal.
//
- // The actions performed here correspond to
- // reshaping the constraint information
- // from global degrees of freedom to local
- // ones (i.e., cell-related DoFs), and also
- // transforming the constraint information
- // from compressed row storage (each local
- // dof that is constrained has a list of
- // constraint entries associated to it)
- // into compressed column storage based on
- // the cell-related DoFs (we have a list of
- // global degrees of freedom, and to each
- // we have a list of local rows where the
- // entries come from). To increase the
- // speed, we additionally store whether an
- // entry is generated directly from the
- // local degrees of freedom or whether it
- // comes from a constraint.
+ // The actions performed here correspond to reshaping the constraint
+ // information from global degrees of freedom to local ones (i.e.,
+ // cell-related DoFs), and also transforming the constraint information from
+ // compressed row storage (each local dof that is constrained has a list of
+ // constraint entries associated to it) into compressed column storage based
+ // on the cell-related DoFs (we have a list of global degrees of freedom,
+ // and to each we have a list of local rows where the entries come from). To
+ // increase the speed, we additionally store whether an entry is generated
+ // directly from the local degrees of freedom or whether it comes from a
+ // constraint.
struct Distributing
{
Distributing (const size_type global_row = numbers::invalid_size_type,
@@ -1266,8 +1253,7 @@ namespace internals
{
global_row = in.global_row;
local_row = in.local_row;
- // the constraints pointer should not
- // contain any data here.
+ // the constraints pointer should not contain any data here.
Assert (constraint_position == numbers::invalid_size_type,
ExcInternalError());
@@ -1281,86 +1267,61 @@ namespace internals
- // this is a cache for constraints that
- // are encountered on a local level.
+ // this is a cache for constraints that are encountered on a local level.
// The functionality is similar to
- // std::vector
- // > >, but tuned so that frequent memory
- // allocation for each entry is
- // avoided. This is not directly used in
- // the user code, but accessed via the
- // GlobalRowsFromLocal.
+ // std::vector > >, but tuned so that
+ // frequent memory allocation for each entry is avoided. The data is put
+ // into a std::vector > and the row length is kept
+ // fixed at row_length. Both the number of rows and the row length can
+ // change is this structure is filled. In that case, the data is
+ // rearranged. This is not directly used in the user code, but accessed via
+ // the GlobalRowsFromLocal.
struct DataCache
{
DataCache ()
:
- element_size (0),
- data (0),
- n_used_elements(0)
+ row_length (8)
{}
- ~DataCache()
- {
- delete [] data;
- data = 0;
- }
-
void reinit ()
{
- Assert (element_size == 0, ExcInternalError());
- element_size = 6;
- data = new std::pair [20*6];
- individual_size.resize(20);
- n_used_elements = 0;
+ individual_size.resize(0);
+ data.resize(0);
}
- size_type element_size;
-
- std::pair *data;
-
- std::vector individual_size;
-
- size_type n_used_elements;
-
size_type insert_new_index (const std::pair &pair)
{
- if (element_size == 0)
- reinit();
- if (n_used_elements == individual_size.size())
- {
- std::pair *new_data =
- new std::pair [2*individual_size.size()*element_size];
- memcpy (new_data, data, individual_size.size()*element_size*
- sizeof(std::pair));
- delete [] data;
- data = new_data;
- individual_size.resize (2*individual_size.size(), 0);
- }
- size_type index = n_used_elements;
- data[index*element_size] = pair;
+ Assert(row_length > 0, ExcInternalError());
+ const unsigned int index = individual_size.size();
+ individual_size.push_back(1);
+ data.resize(individual_size.size()*row_length);
+ data[index*row_length] = pair;
individual_size[index] = 1;
- ++n_used_elements;
return index;
}
void append_index (const size_type index,
const std::pair &pair)
{
- AssertIndexRange (index, n_used_elements);
- const size_type my_size = individual_size[index];
- if (my_size == element_size)
+ AssertIndexRange (index, individual_size.size());
+ const size_type my_length = individual_size[index];
+ if (my_length == row_length)
{
- std::pair *new_data =
- new std::pair [2*individual_size.size()*element_size];
- for (size_type i=0; i));
- delete [] data;
- data = new_data;
- element_size *= 2;
+ AssertDimension(data.size(), individual_size.size()*row_length);
+ // no space left in this row, need to double row_length and
+ // rearrange the data items
+ data.resize(2*data.size());
+ for (size_type i=individual_size.size(); i>0; )
+ {
+ --i;
+ std::memmove(&data[i*row_length*2], &data[i*row_length],
+ individual_size[i]*
+ sizeof(std::pair));
+ }
+ row_length *= 2;
}
- data[index*element_size+my_size] = pair;
- individual_size[index]++;
+ data[index*row_length+my_length] = pair;
+ individual_size[index] = my_length + 1;
}
size_type
@@ -1372,60 +1333,61 @@ namespace internals
const std::pair *
get_entry (const size_type index) const
{
- return &data[index*element_size];
+ return &data[index*row_length];
}
+
+ size_type row_length;
+
+ std::vector > data;
+
+ std::vector individual_size;
};
- // collects all the global rows from a
- // local contribution (cell) and their
- // origin (direct/constraint). this is
- // basically a vector consisting of
- // "Distributing" structs using access via
- // the DataCache. Provides some
+ // collects all the global rows from a local contribution (cell) and their
+ // origin (direct/constraint). this is basically a vector consisting of
+ // "Distributing" structs using access via the DataCache. Provides some
// specialized sort and insert functions.
//
- // in case there are no constraints, this is
- // basically a list of pairs with
- // the first index being the global index and
- // the second index the local index. The list
- // is sorted with respect to the global index.
+ // in case there are no constraints, this is basically a list of pairs
+ // with the first index being the global index and the second
+ // index the local index. The list is sorted with respect to the global
+ // index.
//
- // in case there are constraints, a global dof
- // might get a contribution also because it
- // gets data from a constrained dof. This
- // means that a global dof might also have
- // indirect contributions from a local dof via
- // a constraint, besides the direct ones.
+ // in case there are constraints, a global dof might get a contribution also
+ // because it gets data from a constrained dof. This means that a global dof
+ // might also have indirect contributions from a local dof via a constraint,
+ // besides the direct ones.
//
- // The actions performed here correspond to
- // reshaping the constraint information
- // from global degrees of freedom to local
- // ones (i.e., cell-related DoFs), and also
- // transforming the constraint information
- // from compressed row storage (each local
- // dof that is constrained has a list of
- // constraint entries associated to it)
- // into compressed column storage based on
- // the cell-related DoFs (we have a list of
- // global degrees of freedom, and to each
- // we have a list of local rows where the
- // entries come from). To increase the
- // speed, we additionally store whether an
- // entry is generated directly from the
- // local degrees of freedom or whether it
- // comes from a constraint.
+ // The actions performed here correspond to reshaping the constraint
+ // information from global degrees of freedom to local ones (i.e.,
+ // cell-related DoFs), and also transforming the constraint information from
+ // compressed row storage (each local dof that is constrained has a list of
+ // constraint entries associated to it) into compressed column storage based
+ // on the cell-related DoFs (we have a list of global degrees of freedom,
+ // and to each we have a list of local rows where the entries come from). To
+ // increase the speed, we additionally store whether an entry is generated
+ // directly from the local degrees of freedom or whether it comes from a
+ // constraint.
class GlobalRowsFromLocal
{
public:
- GlobalRowsFromLocal (const size_type n_local_rows)
+ GlobalRowsFromLocal ()
:
- total_row_indices (n_local_rows),
- n_active_rows (n_local_rows),
+ n_active_rows (0),
n_inhomogeneous_rows (0)
{}
+ void reinit (const size_type n_local_rows)
+ {
+ total_row_indices.resize(n_local_rows);
+ for (unsigned int i=0; i total_row_indices;
private:
- // holds the actual data from
- // the constraints
+ // holds the actual data from the constraints
DataCache data_cache;
- // how many rows there are,
- // constraints disregarded
+ // how many rows there are, constraints disregarded
size_type n_active_rows;
- // the number of rows with
- // inhomogeneous constraints
+ // the number of rows with inhomogeneous constraints
size_type n_inhomogeneous_rows;
};
- // a function that appends an additional
- // row to the list of values, or appends a
- // value to an already existing
- // row. Similar functionality as for
- // std::map, but
- // here done for a
- // std::vector, much faster
- // for short lists as we have them here
+ // a function that appends an additional row to the list of values, or
+ // appends a value to an already existing row. Similar functionality as for
+ // std::map, but here done for a
+ // std::vector, much faster for short lists as we have them
+ // here
inline
void
GlobalRowsFromLocal::insert_index (const size_type global_row,
@@ -1632,8 +1562,7 @@ namespace internals
Distributing row_value (global_row);
std::pair constraint (local_row, constraint_value);
- // check whether the list was really
- // sorted before entering here
+ // check whether the list was really sorted before entering here
for (size_type i=1; iconstraint_position, constraint);
}
- // this sort algorithm sorts
- // std::vector, but does not
- // take the constraints into account. this
- // means that in case that constraints are
- // already inserted, this function does not
- // work as expected. Use shellsort, which
- // is very fast in case the indices are
- // already sorted (which is the usual case
- // with DG elements), and not too slow in
- // other cases
+ // this sort algorithm sorts std::vector, but does not take
+ // the constraints into account. this means that in case that constraints
+ // are already inserted, this function does not work as expected. Use
+ // shellsort, which is very fast in case the indices are already sorted
+ // (which is the usual case with DG elements), and not too slow in other
+ // cases
inline
void
GlobalRowsFromLocal::sort ()
@@ -1671,12 +1596,10 @@ namespace internals
size_type i, j, j2, temp, templ, istep;
size_type step;
- // check whether the
- // constraints are really empty.
+ // check whether the constraints are really empty.
const size_type length = size();
- // make sure that we are in the
- // range of the vector
+ // make sure that we are in the range of the vector
AssertIndexRange (length, total_row_indices.size()+1);
for (size_type i=0; i
inline
void
@@ -1746,9 +1664,9 @@ namespace internals
block_starts[i] = first_block - global_rows.total_row_indices.begin();
block_indices = first_block;
}
+ block_starts[num_blocks] = n_active_rows;
- // transform row indices to block-local
- // index space
+ // transform row indices to block-local index space
for (size_type i=block_starts[1]; i instead of
- // GlobalRowsFromLocal. Used in functions
- // for sparsity patterns.
+ // same as before, but for std::vector instead of
+ // GlobalRowsFromLocal. Used in functions for sparsity patterns.
template
inline
void
@@ -1785,9 +1701,9 @@ namespace internals
block_starts[i] = first_block - row_indices.begin();
col_indices = first_block;
}
+ block_starts[num_blocks] = row_indices.size();
- // transform row indices to local index
- // space
+ // transform row indices to local index space
for (size_type i=block_starts[1]; i
inline
void
@@ -1874,12 +1782,9 @@ namespace internals
AssertIndexRange (column_end-1, global_cols.size());
const size_type loc_row = global_rows.local_row(i);
- // fast function if there are no indirect
- // references to any of the local rows at
- // all on this set of dofs (saves a lot
- // of checks). the only check we actually
- // need to perform is whether the matrix
- // element is zero.
+ // fast function if there are no indirect references to any of the local
+ // rows at all on this set of dofs (saves a lot of checks). the only check
+ // we actually need to perform is whether the matrix element is zero.
if (global_rows.have_indirect_rows() == false &&
global_cols.have_indirect_rows() == false)
{
@@ -1899,8 +1804,7 @@ namespace internals
}
}
- // more difficult part when there are
- // indirect references and when we need
+ // more difficult part when there are indirect references and when we need
// to do some more checks.
else
{
@@ -1909,8 +1813,8 @@ namespace internals
double col_val = resolve_matrix_entry (global_rows, global_cols, i, j,
loc_row, local_matrix);
- // if we got some nontrivial value,
- // append it to the array of values.
+ // if we got some nontrivial value, append it to the array of
+ // values.
if (col_val != 0.)
{
*val_ptr++ = static_cast (col_val);
@@ -1922,8 +1826,8 @@ namespace internals
- // specialized function that can write into
- // the row of a SparseMatrix.
+ // specialized function that can write into the row of a
+ // SparseMatrix.
namespace dealiiSparseMatrix
{
template
@@ -1945,11 +1849,9 @@ namespace internals
}
- // similar as before, now with shortcut for
- // deal.II sparse matrices. this lets us
- // avoid using extra arrays, and does all the
- // operations just in place, i.e., in the
- // respective matrix row
+ // similar as before, now with shortcut for deal.II sparse matrices. this
+ // lets us avoid using extra arrays, and does all the operations just in
+ // place, i.e., in the respective matrix row
template
inline
void
@@ -1976,11 +1878,9 @@ namespace internals
matrix_values = sparse_matrix->begin(row);
const bool optimize_diagonal = sparsity.n_rows() == sparsity.n_cols();
- // distinguish three cases about what can
- // happen for checking whether the diagonal is
- // the first element of the row. this avoids
- // if statements at the innermost loop
- // positions
+ // distinguish three cases about what can happen for checking whether the
+ // diagonal is the first element of the row. this avoids if statements at
+ // the innermost loop positions
if (!optimize_diagonal) // case 1: no diagonal optimization in matrix
{
@@ -2059,8 +1959,7 @@ namespace internals
}
}
}
- // case 3: can't say - need to check inside
- // the loop
+ // case 3: can't say - need to check inside the loop
else if (global_rows.have_indirect_rows() == false)
{
++matrix_values; // jump over diagonal element
@@ -2098,10 +1997,8 @@ namespace internals
- // Same function to resolve all entries that
- // will be added to the given global row
- // global_rows[i] as before, now for sparsity
- // pattern
+ // Same function to resolve all entries that will be added to the given
+ // global row global_rows[i] as before, now for sparsity pattern
inline
void
resolve_matrix_row (const GlobalRowsFromLocal &global_rows,
@@ -2116,9 +2013,8 @@ namespace internals
const size_type loc_row = global_rows.local_row(i);
- // fast function if there are no indirect
- // references to any of the local rows at
- // all on this set of dofs
+ // fast function if there are no indirect references to any of the local
+ // rows at all on this set of dofs
if (global_rows.have_indirect_rows() == false)
{
Assert(loc_row < dof_mask.n_rows(),
@@ -2134,9 +2030,8 @@ namespace internals
}
}
- // slower functions when there are
- // indirect references and when we need
- // to do some more checks.
+ // slower functions when there are indirect references and when we need to
+ // do some more checks.
else
{
for (size_type j=column_start; j
inline void
set_matrix_diagonals (const internals::GlobalRowsFromLocal &global_rows,
@@ -2236,12 +2117,10 @@ add_this_index:
std::fabs(local_matrix(local_row,local_row)) : average_diagonal);
global_matrix.add(global_row, global_row, new_diagonal);
- // if the use_inhomogeneities_for_rhs flag is
- // set to true, the inhomogeneities are used
- // to create the global vector. instead of
- // fill in a zero in the ith components with an
- // inhomogeneity, we set those to:
- // inhomogeneity(i)*global_matrix (i,i).
+ // if the use_inhomogeneities_for_rhs flag is set to true, the
+ // inhomogeneities are used to create the global vector. instead
+ // of fill in a zero in the ith components with an inhomogeneity,
+ // we set those to: inhomogeneity(i)*global_matrix (i,i).
if (use_inhomogeneities_for_rhs == true)
global_vector(global_row) += constraints.get_inhomogeneity(global_row) * new_diagonal;
}
@@ -2250,26 +2129,21 @@ add_this_index:
- // similar function as the one above for
- // setting matrix diagonals, but now doing
- // that for sparsity patterns when setting
- // them up using
- // add_entries_local_to_global. In case we
- // keep constrained entries, add all the rows
- // and columns related to the constrained dof,
- // otherwise just add the diagonal
+ // similar function as the one above for setting matrix diagonals, but now
+ // doing that for sparsity patterns when setting them up using
+ // add_entries_local_to_global. In case we keep constrained entries, add all
+ // the rows and columns related to the constrained dof, otherwise just add
+ // the diagonal
template
inline void
set_sparsity_diagonals (const internals::GlobalRowsFromLocal &global_rows,
- const std::vector &local_dof_indices,
+ const std::vector &local_dof_indices,
const Table<2,bool> &dof_mask,
const bool keep_constrained_entries,
SparsityType &sparsity_pattern)
{
- // if we got constraints, need to add
- // the diagonal element and, if the
- // user requested so, also the rest of
- // the entries in rows and columns
+ // if we got constraints, need to add the diagonal element and, if the
+ // user requested so, also the rest of the entries in rows and columns
// that have been left out above
if (global_rows.n_constraints() > 0)
{
@@ -2290,8 +2164,7 @@ add_this_index:
}
}
else
- // don't keep constrained entries - just
- // add the diagonal.
+ // don't keep constrained entries - just add the diagonal.
sparsity_pattern.add(global_row,global_row);
}
}
@@ -2309,57 +2182,42 @@ add_this_index:
// are related to it.
void
ConstraintMatrix::
-make_sorted_row_list (const std::vector &local_dof_indices,
- internals::GlobalRowsFromLocal &global_rows) const
+make_sorted_row_list (const std::vector &local_dof_indices,
+ internals::GlobalRowsFromLocal &global_rows) const
{
const size_type n_local_dofs = local_dof_indices.size();
AssertDimension (n_local_dofs, global_rows.size());
- // when distributing the local data to
- // the global matrix, we can quite
- // cheaply sort the indices (obviously,
- // this introduces the need for
- // allocating some memory on the way, but
- // we need to do this only for rows,
- // whereas the distribution process
- // itself goes over rows and
- // columns). This has the advantage that
- // when writing into the global matrix,
- // we can make use of the sortedness.
-
- // so the first step is to create a
- // sorted list of all row values that are
- // possible. these values are either the
- // rows from unconstrained dofs, or some
- // indices introduced by dofs constrained
- // to a combination of some other
- // dofs. regarding the data type, choose
- // an STL vector of a pair of unsigned
- // ints (for global columns) and internal
- // data (containing local columns +
- // possible jumps from
- // constraints). Choosing an STL map or
- // anything else M.K. knows of would be
- // much more expensive here!
-
- // cache whether we have to resolve any
- // indirect rows generated from resolving
- // constrained dofs.
+ // when distributing the local data to the global matrix, we can quite
+ // cheaply sort the indices (obviously, this introduces the need for
+ // allocating some memory on the way, but we need to do this only for rows,
+ // whereas the distribution process itself goes over rows and columns). This
+ // has the advantage that when writing into the global matrix, we can make
+ // use of the sortedness.
+
+ // so the first step is to create a sorted list of all row values that are
+ // possible. these values are either the rows from unconstrained dofs, or
+ // some indices introduced by dofs constrained to a combination of some
+ // other dofs. regarding the data type, choose an STL vector of a pair of
+ // unsigned ints (for global columns) and internal data (containing local
+ // columns + possible jumps from constraints). Choosing an STL map or
+ // anything else M.K. knows of would be much more expensive here!
+
+ // cache whether we have to resolve any indirect rows generated from
+ // resolving constrained dofs.
size_type added_rows = 0;
- // first add the indices in an unsorted
- // way and only keep track of the
- // constraints that appear. They are
- // resolved in a second step.
+ // first add the indices in an unsorted way and only keep track of the
+ // constraints that appear. They are resolved in a second step.
for (size_type i = 0; i &local_dof_indices,
-// Same function as before, but now do
-// only extract the global indices
-// that come from the local ones
-// without storing their origin. Used
-// for sparsity pattern generation.
+// Same function as before, but now do only extract the global indices that
+// come from the local ones without storing their origin. Used for sparsity
+// pattern generation.
inline
void
ConstraintMatrix::
@@ -2413,8 +2269,7 @@ make_sorted_row_list (const std::vector &local_dof_indices,
{
const size_type local_row = active_dofs.back();
- // remove constrained entry since we
- // are going to resolve it in place
+ // remove constrained entry since we are going to resolve it in place
active_dofs.pop_back();
const size_type global_row = local_dof_indices[local_row];
const ConstraintLine &position =
@@ -2425,9 +2280,8 @@ make_sorted_row_list (const std::vector &local_dof_indices,
if (active_dofs[active_dofs.size()-i] < new_index)
active_dofs.insert(active_dofs.end()-i+1,new_index);
- // make binary search to find where to
- // put the new index in order to keep
- // the list sorted
+ // make binary search to find where to put the new index in order to
+ // keep the list sorted
else
{
std::vector::iterator it =
@@ -2443,8 +2297,7 @@ make_sorted_row_list (const std::vector &local_dof_indices,
-// Resolve the constraints from the vector and
-// apply inhomogeneities.
+// Resolve the constraints from the vector and apply inhomogeneities.
inline
double
ConstraintMatrix::
@@ -2457,10 +2310,9 @@ resolve_vector_entry (const size_type i,
const size_type loc_row = global_rows.local_row(i);
const size_type n_inhomogeneous_rows = global_rows.n_inhomogeneities();
double val = 0;
- // has a direct contribution from some local
- // entry. If we have inhomogeneous
- // constraints, compute the contribution of
- // the inhomogeneity in the current row.
+ // has a direct contribution from some local entry. If we have inhomogeneous
+ // constraints, compute the contribution of the inhomogeneity in the current
+ // row.
if (loc_row != numbers::invalid_size_type)
{
val = local_vector(loc_row);
@@ -2488,9 +2340,8 @@ resolve_vector_entry (const size_type i,
}
-// internal implementation for
-// distribute_local_to_global for
-// standard (non-block) matrices
+// internal implementation for distribute_local_to_global for standard
+// (non-block) matrices
template
void
ConstraintMatrix::distribute_local_to_global (
@@ -2502,9 +2353,8 @@ ConstraintMatrix::distribute_local_to_global (
bool use_inhomogeneities_for_rhs,
internal::bool2type) const
{
- // check whether we work on real vectors
- // or we just used a dummy when calling
- // the other function above.
+ // check whether we work on real vectors or we just used a dummy when
+ // calling the other function above.
const bool use_vectors = (local_vector.size() == 0 &&
global_vector.size() == 0) ? false : true;
typedef typename MatrixType::value_type number;
@@ -2522,62 +2372,76 @@ ConstraintMatrix::distribute_local_to_global (
Assert (lines.empty() || sorted == true, ExcMatrixNotClosed());
const size_type n_local_dofs = local_dof_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ // TODO: might want to have a scoped variable for in_use here and in the
+ // methods below
+ my_scratch_data.in_use = true;
+
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // create arrays for the column data
- // (indices and values) that will then be
- // written into the matrix. Shortcut for
- // deal.II sparse matrix
- std::vector cols;
- std::vector vals;
+ // create arrays for the column data (indices and values) that will then be
+ // written into the matrix. Shortcut for deal.II sparse matrix. We can use
+ // the scratch data if we have a double matrix. Otherwise, we need to create
+ // an array in any case since we cannot know about the actual data type in
+ // the ConstraintMatrix class (unless we do cast). This involves a little
+ // bit of logic to determine the type of the matrix value.
+ std::vector & cols = my_scratch_data.columns;
+ std::vector & vals = my_scratch_data.values;
+ std::vector values_non_double;
SparseMatrix *sparse_matrix
= dynamic_cast *>(&global_matrix);
if (use_dealii_matrix == false)
{
cols.resize (n_actual_dofs);
- vals.resize (n_actual_dofs);
+ if (types_are_equal::value == false)
+ values_non_double.resize(n_actual_dofs);
+ else
+ vals.resize (n_actual_dofs);
}
else
Assert (sparse_matrix != 0, ExcInternalError());
- // now do the actual job. go through all
- // the global rows that we will touch and
- // call resolve_matrix_row for each of
- // those.
+ // now do the actual job. go through all the global rows that we will touch
+ // and call resolve_matrix_row for each of those.
for (size_type i=0; i::value ?
+ reinterpret_cast(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_rows, i, 0,
n_actual_dofs,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type)(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
- global_matrix.add(row, n_values, &cols[0], &vals[0], false, true);
+ global_matrix.add(row, n_values, &cols[0], val_ptr-n_values, false,
+ true);
}
else
internals::resolve_matrix_row (global_rows, i, 0, n_actual_dofs,
local_matrix, sparse_matrix);
- // now to the vectors. besides doing the
- // same job as we did above (i.e.,
- // distribute the content of the local
- // vector into the global one), need to
- // account for inhomogeneities here: thie
- // corresponds to eliminating the
- // respective column in the local matrix
- // with value on the right hand side.
+ // now to the vectors. besides doing the same job as we did above (i.e.,
+ // distribute the content of the local vector into the global one), need
+ // to account for inhomogeneities here: thie corresponds to eliminating
+ // the respective column in the local matrix with value on the right
+ // hand side.
if (use_vectors == true)
{
const double val = resolve_vector_entry (i, global_rows,
@@ -2593,6 +2457,7 @@ ConstraintMatrix::distribute_local_to_global (
internals::set_matrix_diagonals (global_rows, local_dof_indices,
local_matrix, *this,
global_matrix, global_vector, use_inhomogeneities_for_rhs);
+ my_scratch_data.in_use = false;
}
@@ -2613,46 +2478,62 @@ ConstraintMatrix::distribute_local_to_global (
const size_type n_local_row_dofs = row_indices.size();
const size_type n_local_col_dofs = col_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_row_dofs);
- internals::GlobalRowsFromLocal global_cols (n_local_col_dofs);
+
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ if (my_scratch_data.global_columns.get() == 0)
+ my_scratch_data.global_columns.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_row_dofs);
+ internals::GlobalRowsFromLocal &global_cols = *my_scratch_data.global_columns;
+ global_cols.reinit(n_local_col_dofs);
make_sorted_row_list (row_indices, global_rows);
make_sorted_row_list (col_indices, global_cols);
const size_type n_actual_row_dofs = global_rows.size();
const size_type n_actual_col_dofs = global_cols.size();
- // create arrays for the column data
- // (indices and values) that will then be
- // written into the matrix. Shortcut for
- // deal.II sparse matrix
- std::vector cols (n_actual_col_dofs);
- std::vector vals (n_actual_col_dofs);
+ // create arrays for the column data (indices and values) that will then be
+ // written into the matrix. Shortcut for deal.II sparse matrix
+ std::vector & cols = my_scratch_data.columns;
+ std::vector & vals = my_scratch_data.values;
+ std::vector values_non_double;
+ cols.resize(n_actual_col_dofs);
+ if (types_are_equal::value == true)
+ vals.resize(n_actual_col_dofs);
+ else
+ values_non_double.resize(n_actual_col_dofs);
// now do the actual job.
for (size_type i=0; i::value ?
+ reinterpret_cast(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_cols, i, 0,
n_actual_col_dofs,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type)(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
- global_matrix.add(row, n_values, &cols[0], &vals[0], false, true);
+ global_matrix.add(row, n_values, &cols[0], val_ptr-n_values,
+ false, true);
}
+
+ my_scratch_data.in_use = false;
}
-// similar function as above, but now
-// specialized for block matrices. See
-// the other function for additional
-// comments.
+// similar function as above, but now specialized for block matrices. See the
+// other function for additional comments.
template
void
ConstraintMatrix::
@@ -2682,12 +2563,22 @@ distribute_local_to_global (const FullMatrix &local_matrix,
}
Assert (sorted == true, ExcMatrixNotClosed());
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
const size_type n_local_dofs = local_dof_indices.size();
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
+
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- std::vector global_indices;
+ std::vector &global_indices = my_scratch_data.vector_indices;
if (use_vectors == true)
{
global_indices.resize(n_actual_dofs);
@@ -2695,25 +2586,27 @@ distribute_local_to_global (const FullMatrix &local_matrix,
global_indices[i] = global_rows.global_row(i);
}
- // additional construct that also takes
- // care of block indices.
+ // additional construct that also takes care of block indices.
const size_type num_blocks = global_matrix.n_block_rows();
- std::vector block_starts(num_blocks+1, n_actual_dofs);
+ std::vector &block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
internals::make_block_starts (global_matrix, global_rows, block_starts);
- std::vector cols;
- std::vector vals;
+ std::vector & cols = my_scratch_data.columns;
+ std::vector & vals = my_scratch_data.values;
+ std::vector values_non_double;
if (use_dealii_matrix == false)
{
cols.resize (n_actual_dofs);
- vals.resize (n_actual_dofs);
+ if (types_are_equal::value == true)
+ vals.resize(n_actual_dofs);
+ else
+ values_non_double.resize(n_actual_dofs);
}
- // the basic difference to the non-block
- // variant from now onwards is that we go
- // through the blocks of the matrix
- // separately, which allows us to set the
- // block entries individually
+ // the basic difference to the non-block variant from now onwards is that we
+ // go through the blocks of the matrix separately, which allows us to set
+ // the block entries individually
for (size_type block=0; block &local_matrix,
if (use_dealii_matrix == false)
{
size_type *col_ptr = &cols[0];
- number *val_ptr = &vals[0];
+ number *val_ptr = types_are_equal::value ?
+ reinterpret_cast(&vals[0]) : &values_non_double[0];
internals::resolve_matrix_row (global_rows, global_rows, i,
start_block, end_block,
local_matrix, col_ptr, val_ptr);
const size_type n_values = col_ptr - &cols[0];
- Assert (n_values == (size_type )(val_ptr - &vals[0]),
- ExcInternalError());
if (n_values > 0)
global_matrix.block(block, block_col).add(row, n_values,
- &cols[0], &vals[0],
+ &cols[0],
+ val_ptr-n_values,
false, true);
}
else
@@ -2768,6 +2661,8 @@ distribute_local_to_global (const FullMatrix &local_matrix,
internals::set_matrix_diagonals (global_rows, local_dof_indices,
local_matrix, *this,
global_matrix, global_vector, use_inhomogeneities_for_rhs);
+
+ my_scratch_data.in_use = false;
}
@@ -2791,35 +2686,34 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
AssertDimension (dof_mask.n_cols(), n_local_dofs);
}
- // if the dof mask is not active, all we
- // have to do is to add some indices in a
- // matrix format. To do this, we first
- // create an array of all the indices
- // that are to be added. these indices
- // are the local dof indices plus some
- // indices that come from constraints.
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
+ // if the dof mask is not active, all we have to do is to add some indices
+ // in a matrix format. To do this, we first create an array of all the
+ // indices that are to be added. these indices are the local dof indices
+ // plus some indices that come from constraints.
if (dof_mask_is_active == false)
{
- std::vector actual_dof_indices (n_local_dofs);
+ std::vector & actual_dof_indices = my_scratch_data.columns;
+ actual_dof_indices.resize(n_local_dofs);
make_sorted_row_list (local_dof_indices, actual_dof_indices);
const size_type n_actual_dofs = actual_dof_indices.size();
- // now add the indices we collected above
- // to the sparsity pattern. Very easy
- // here - just add the same array to all
- // the rows...
+ // now add the indices we collected above to the sparsity pattern. Very
+ // easy here - just add the same array to all the rows...
for (size_type i=0; i &local_dof_indices,
sparsity_pattern.add (local_dof_indices[i], local_dof_indices[i]);
}
+ my_scratch_data.in_use = false;
return;
}
- // complicated case: we need to filter
- // out some indices. then the function
- // gets similar to the function for
- // distributing matrix entries, see there
+ // complicated case: we need to filter out some indices. then the function
+ // gets similar to the function for distributing matrix entries, see there
// for additional comments.
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // create arrays for the column indices
- // that will then be written into the
+ // create arrays for the column indices that will then be written into the
// sparsity pattern.
- std::vector cols (n_actual_dofs);
+ std::vector & cols = my_scratch_data.columns;
+ cols.resize(n_actual_dofs);
for (size_type i=0; i &local_dof_indices,
internals::resolve_matrix_row (global_rows, i, 0, n_actual_dofs,
dof_mask, col_ptr);
- // finally, write all the information
- // that accumulated under the given
- // process into the global matrix row and
- // into the vector
+ // finally, write all the information that accumulated under the given
+ // process into the global matrix row and into the vector
if (col_ptr != cols.begin())
sparsity_pattern.add_entries(row, cols.begin(), col_ptr,
true);
@@ -2869,6 +2763,7 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
internals::set_sparsity_diagonals (global_rows, local_dof_indices,
dof_mask, keep_constrained_entries,
sparsity_pattern);
+ my_scratch_data.in_use = false;
}
@@ -2879,9 +2774,9 @@ void
ConstraintMatrix::
add_entries_local_to_global (const std::vector &row_indices,
const std::vector &col_indices,
- SparsityType &sparsity_pattern,
- const bool keep_constrained_entries,
- const Table<2,bool> &dof_mask) const
+ SparsityType &sparsity_pattern,
+ const bool keep_constrained_entries,
+ const Table<2,bool> &dof_mask) const
{
const size_type n_local_rows = row_indices.size();
const size_type n_local_cols = col_indices.size();
@@ -2889,13 +2784,10 @@ add_entries_local_to_global (const std::vector &row_indices,
if (dof_mask.n_rows() == n_local_rows && dof_mask.n_cols() == n_local_cols)
dof_mask_is_active = true;
- // if the dof mask is not active, all we
- // have to do is to add some indices in a
- // matrix format. To do this, we first
- // create an array of all the indices
- // that are to be added. these indices
- // are the local dof indices plus some
- // indices that come from constraints.
+ // if the dof mask is not active, all we have to do is to add some indices
+ // in a matrix format. To do this, we first create an array of all the
+ // indices that are to be added. these indices are the local dof indices
+ // plus some indices that come from constraints.
if (dof_mask_is_active == false)
{
std::vector actual_row_indices (n_local_rows);
@@ -2904,10 +2796,8 @@ add_entries_local_to_global (const std::vector &row_indices,
make_sorted_row_list (col_indices, actual_col_indices);
const size_type n_actual_rows = actual_row_indices.size();
- // now add the indices we collected above
- // to the sparsity pattern. Very easy
- // here - just add the same array to all
- // the rows...
+ // now add the indices we collected above to the sparsity pattern. Very
+ // easy here - just add the same array to all the rows...
for (size_type i=0; i &row_indices,
return;
}
- // if constrained entries should be
- // kept, need to add rows and columns
- // of those to the sparsity pattern
+ // if constrained entries should be kept, need to add rows and columns of
+ // those to the sparsity pattern
if (keep_constrained_entries == true)
{
for (size_type i=0; i &local_dof_indices,
const Table<2,bool> &dof_mask,
internal::bool2type ) const
{
- // just as the other
- // add_entries_local_to_global function,
- // but now specialized for block
- // matrices.
+ // just as the other add_entries_local_to_global function, but now
+ // specialized for block matrices.
Assert (sparsity_pattern.n_rows() == sparsity_pattern.n_cols(), ExcNotQuadratic());
Assert (sparsity_pattern.n_block_rows() == sparsity_pattern.n_block_cols(),
ExcNotQuadratic());
@@ -2959,6 +2846,12 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
const size_type n_local_dofs = local_dof_indices.size();
const size_type num_blocks = sparsity_pattern.n_block_rows();
+ ScratchData &my_scratch_data = scratch_data.get();
+ Assert(my_scratch_data.in_use == false,
+ ExcMessage("Access to thread-local scratch data tried, but it is already "
+ "in use"));
+ my_scratch_data.in_use = true;
+
bool dof_mask_is_active = false;
if (dof_mask.n_rows() == n_local_dofs)
{
@@ -2968,13 +2861,14 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
if (dof_mask_is_active == false)
{
- std::vector actual_dof_indices (n_local_dofs);
+ std::vector & actual_dof_indices = my_scratch_data.columns;
+ actual_dof_indices.resize(n_local_dofs);
make_sorted_row_list (local_dof_indices, actual_dof_indices);
const size_type n_actual_dofs = actual_dof_indices.size();
- // additional construct that also takes
- // care of block indices.
- std::vector block_starts(num_blocks+1, n_actual_dofs);
+ // additional construct that also takes care of block indices.
+ std::vector &block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
internals::make_block_starts (sparsity_pattern, actual_dof_indices,
block_starts);
@@ -3014,28 +2908,29 @@ add_entries_local_to_global (const std::vector &local_dof_indices,
sparsity_pattern.add (local_dof_indices[i], local_dof_indices[i]);
}
+ my_scratch_data.in_use = false;
return;
}
- // difficult case with dof_mask, similar
- // to the distribute_local_to_global
+ // difficult case with dof_mask, similar to the distribute_local_to_global
// function for block matrices
- internals::GlobalRowsFromLocal global_rows (n_local_dofs);
+ if (my_scratch_data.global_rows.get() == 0)
+ my_scratch_data.global_rows.reset(new internals::GlobalRowsFromLocal());
+ internals::GlobalRowsFromLocal &global_rows = *my_scratch_data.global_rows;
+ global_rows.reinit(n_local_dofs);
make_sorted_row_list (local_dof_indices, global_rows);
const size_type n_actual_dofs = global_rows.size();
- // additional construct that also takes
- // care of block indices.
- std::vector block_starts(num_blocks+1, n_actual_dofs);
- internals::make_block_starts(sparsity_pattern, global_rows,
- block_starts);
+ // additional construct that also takes care of block indices.
+ std::vector & block_starts = my_scratch_data.block_starts;
+ block_starts.resize(num_blocks+1);
+ internals::make_block_starts(sparsity_pattern, global_rows, block_starts);
- std::vector cols (n_actual_dofs);
+ std::vector &cols = my_scratch_data.columns;
+ cols.resize(n_actual_dofs);
- // the basic difference to the
- // non-block variant from now onwards
- // is that we go through the blocks
- // of the matrix separately.
+ // the basic difference to the non-block variant from now onwards is that we
+ // go through the blocks of the matrix separately.
for (size_type block=0; block &local_dof_indices,
internals::set_sparsity_diagonals (global_rows, local_dof_indices,
dof_mask, keep_constrained_entries,
sparsity_pattern);
+ my_scratch_data.in_use = false;
}
DEAL_II_NAMESPACE_CLOSE
#endif
-
diff --git a/deal.II/include/deal.II/lac/parallel_vector.h b/deal.II/include/deal.II/lac/parallel_vector.h
index c568a4aba7..fbc865798f 100644
--- a/deal.II/include/deal.II/lac/parallel_vector.h
+++ b/deal.II/include/deal.II/lac/parallel_vector.h
@@ -1185,11 +1185,9 @@ namespace parallel
{
Assert (c.partitioner.get() != 0, ExcNotInitialized());
- // check whether the two vectors use the same
- // parallel partitioner. if not, check if all
- // local ranges are the same (that way, we can
- // exchange data between different parallel
- // layouts)
+ // check whether the two vectors use the same parallel partitioner. if
+ // not, check if all local ranges are the same (that way, we can
+ // exchange data between different parallel layouts)
if (partitioner.get() == 0)
reinit (c, true);
else if (partitioner.get() != c.partitioner.get())
diff --git a/deal.II/include/deal.II/lac/pointer_matrix.h b/deal.II/include/deal.II/lac/pointer_matrix.h
index 9235de13b0..6c0d5ca692 100644
--- a/deal.II/include/deal.II/lac/pointer_matrix.h
+++ b/deal.II/include/deal.II/lac/pointer_matrix.h
@@ -398,7 +398,7 @@ private:
* product (#vmult()) and scalar multiplication (#Tvmult()) functions
* of the Vector class.
*
- * @author Guidl Kanschat, 2006
+ * @author Guido Kanschat, 2006
*/
template
class PointerMatrixVector : public PointerMatrixBase >
diff --git a/deal.II/include/deal.II/numerics/vector_tools.templates.h b/deal.II/include/deal.II/numerics/vector_tools.templates.h
index e814f047db..5462558aff 100644
--- a/deal.II/include/deal.II/numerics/vector_tools.templates.h
+++ b/deal.II/include/deal.II/numerics/vector_tools.templates.h
@@ -1579,8 +1579,7 @@ namespace VectorTools
"element."));
- // if for whatever reason we were
- // passed an empty map, return
+ // if for whatever reason we were passed an empty map, return
// immediately
if (function_map.size() == 0)
return;
@@ -1603,78 +1602,48 @@ namespace VectorTools
std::vector > dof_locations;
dof_locations.reserve (DoFTools::max_dofs_per_face(dof));
- // array to store the values of
- // the boundary function at the
- // boundary points. have two arrays
- // for scalar and vector functions
- // to use the more efficient one
- // respectively
+ // array to store the values of the boundary function at the boundary
+ // points. have two arrays for scalar and vector functions to use the
+ // more efficient one respectively
std::vector dof_values_scalar;
std::vector > dof_values_system;
dof_values_scalar.reserve (DoFTools::max_dofs_per_face (dof));
dof_values_system.reserve (DoFTools::max_dofs_per_face (dof));
- // before we start with the loop
- // over all cells create an
- // hp::FEValues object that holds
- // the interpolation points of all
- // finite elements that may ever be
- // in use
+ // before we start with the loop over all cells create an hp::FEValues
+ // object that holds the interpolation points of all finite elements
+ // that may ever be in use
dealii::hp::FECollection finite_elements (dof.get_fe());
dealii::hp::QCollection q_collection;
for (unsigned int f=0; f &fe = finite_elements[f];
- // generate a quadrature rule
- // on the face from the unit
- // support points. this will be
- // used to obtain the
- // quadrature points on the
+ // generate a quadrature rule on the face from the unit support
+ // points. this will be used to obtain the quadrature points on the
// real cell's face
//
- // to do this, we check whether
- // the FE has support points on
- // the face at all:
+ // to do this, we check whether the FE has support points on the
+ // face at all:
if (fe.has_face_support_points())
q_collection.push_back (Quadrature(fe.get_unit_face_support_points()));
else
{
- // if not, then we should
- // try a more clever
- // way. the idea is that a
- // finite element may not
- // offer support points for
- // all its shape functions,
- // but maybe only some. if
- // it offers support points
- // for the components we
- // are interested in in
- // this function, then
- // that's fine. if not, the
- // function we call in the
- // finite element will
- // raise an exception. the
- // support points for the
- // other shape functions
- // are left uninitialized
- // (well, initialized by
- // the default
- // constructor), since we
+ // if not, then we should try a more clever way. the idea is
+ // that a finite element may not offer support points for all
+ // its shape functions, but maybe only some. if it offers
+ // support points for the components we are interested in in
+ // this function, then that's fine. if not, the function we call
+ // in the finite element will raise an exception. the support
+ // points for the other shape functions are left uninitialized
+ // (well, initialized by the default constructor), since we
// don't need them anyway.
//
- // As a detour, we must
- // make sure we only query
- // face_system_to_component_index
- // if the index corresponds
- // to a primitive shape
- // function. since we know
- // that all the components
- // we are interested in are
- // primitive (by the above
- // check), we can safely
- // put such a check in
- // front
+ // As a detour, we must make sure we only query
+ // face_system_to_component_index if the index corresponds to a
+ // primitive shape function. since we know that all the
+ // components we are interested in are primitive (by the above
+ // check), we can safely put such a check in front
std::vector > unit_support_points (fe.dofs_per_face);
for (unsigned int i=0; i(unit_support_points));
}
}
- // now that we have a q_collection
- // object with all the right
- // quadrature points, create an
- // hp::FEFaceValues object that we
- // can use to evaluate the boundary
- // values at
+ // now that we have a q_collection object with all the right quadrature
+ // points, create an hp::FEFaceValues object that we can use to evaluate
+ // the boundary values at
dealii::hp::MappingCollection mapping_collection (mapping);
dealii::hp::FEFaceValues x_fe_values (mapping_collection, finite_elements, q_collection,
update_quadrature_points);
@@ -1705,15 +1671,11 @@ namespace VectorTools
{
const FiniteElement &fe = cell->get_fe();
- // we can presently deal only with
- // primitive elements for boundary
- // values. this does not preclude
- // us using non-primitive elements
- // in components that we aren't
- // interested in, however. make
- // sure that all shape functions
- // that are non-zero for the
- // components we are interested in,
+ // we can presently deal only with primitive elements for
+ // boundary values. this does not preclude us using
+ // non-primitive elements in components that we aren't
+ // interested in, however. make sure that all shape functions
+ // that are non-zero for the components we are interested in,
// are in fact primitive
for (unsigned int i=0; iget_fe().dofs_per_cell; ++i)
{
@@ -1732,15 +1694,9 @@ namespace VectorTools
const typename DH::face_iterator face = cell->face(face_no);
const types::boundary_id boundary_component = face->boundary_indicator();
- // see if this face is
- // part of the
- // boundaries for which
- // we are supposed to
- // do something, and
- // also see if the
- // finite element in
- // use here has DoFs on
- // the face at all
+ // see if this face is part of the boundaries for which we are
+ // supposed to do something, and also see if the finite element
+ // in use here has DoFs on the face at all
if ((function_map.find(boundary_component) != function_map.end())
&&
(cell->get_fe().dofs_per_face > 0))
@@ -1750,9 +1706,8 @@ namespace VectorTools
const dealii::FEFaceValues &fe_values =
x_fe_values.get_present_fe_values();
- // get indices, physical location and
- // boundary values of dofs on this
- // face
+ // get indices, physical location and boundary values of
+ // dofs on this face
face_dofs.resize (fe.dofs_per_face);
face->get_dof_indices (face_dofs, cell->active_fe_index());
const std::vector > &dof_locations
@@ -1760,12 +1715,8 @@ namespace VectorTools
if (fe_is_system)
{
- // resize
- // array. avoid
- // construction of a
- // memory allocating
- // temporary if
- // possible
+ // resize array. avoid construction of a memory
+ // allocating temporary if possible
if (dof_values_system.size() < fe.dofs_per_face)
dof_values_system.resize (fe.dofs_per_face,
dealii::Vector(fe.n_components()));
@@ -1775,17 +1726,10 @@ namespace VectorTools
function_map.find(boundary_component)->second
->vector_value_list (dof_locations, dof_values_system);
- // enter those dofs
- // into the list that
- // match the
- // component
- // signature. avoid
- // the usual
- // complication that
- // we can't just use
- // *_system_to_component_index
- // for non-primitive
- // FEs
+ // enter those dofs into the list that match the
+ // component signature. avoid the usual complication
+ // that we can't just use *_system_to_component_index
+ // for non-primitive FEs
for (unsigned int i=0; isecond
->value_list (dof_locations, dof_values_scalar, 0);
diff --git a/deal.II/source/CMakeLists.txt b/deal.II/source/CMakeLists.txt
index cabda8f8fd..dd6de69d3e 100644
--- a/deal.II/source/CMakeLists.txt
+++ b/deal.II/source/CMakeLists.txt
@@ -14,6 +14,8 @@
##
## ---------------------------------------------------------------------
+MESSAGE(STATUS "Setup library")
+
#
# Compile the deal.II library
#
@@ -114,3 +116,5 @@ INSTALL(EXPORT ${DEAL_II_PROJECT_CONFIG_NAME}Targets
DESTINATION ${DEAL_II_PROJECT_CONFIG_RELDIR}
COMPONENT library
)
+
+MESSAGE(STATUS "Setup library - Done")
diff --git a/deal.II/source/grid/grid_tools.cc b/deal.II/source/grid/grid_tools.cc
index 7cd43ae0fb..f62d935d63 100644
--- a/deal.II/source/grid/grid_tools.cc
+++ b/deal.II/source/grid/grid_tools.cc
@@ -59,6 +59,13 @@ namespace GridTools
return tria;
}
+ template
+ const Triangulation &
+ get_tria(const parallel::distributed::Triangulation &tria)
+ {
+ return tria;
+ }
+
template class Container, int spacedim>
const Triangulation &
get_tria(const Container