From: Wolfgang Bangerth Date: Wed, 3 Mar 2004 01:14:29 +0000 (+0000) Subject: Merge in my changes from the PETSc branch. X-Git-Tag: v8.0.0~15699 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=594889a1ff0108a59a8b1b35f85c59dee48b20b4;p=dealii.git Merge in my changes from the PETSc branch. git-svn-id: https://svn.dealii.org/trunk@8640 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/Makefile b/deal.II/Makefile index fc48866910..c2a97fd41d 100644 --- a/deal.II/Makefile +++ b/deal.II/Makefile @@ -69,6 +69,7 @@ deps: common/scripts/make_dependencies cd $D/base && $(MAKE) $(MAKEOPTIONS) Makefile.dep cd $D/lac && $(MAKE) $(MAKEOPTIONS) Makefile.dep cd $D/deal.II && $(MAKE) $(MAKEOPTIONS) Makefile.dep + cd $D/lib && $(MAKE) $(MAKEOPTIONS) external-links common/scripts/make_dependencies: cd $D/common/scripts && $(MAKE) $(MAKEOPTIONS) diff --git a/deal.II/aclocal.m4 b/deal.II/aclocal.m4 index 9ec3c3f678..56716690e5 100644 --- a/deal.II/aclocal.m4 +++ b/deal.II/aclocal.m4 @@ -1454,6 +1454,42 @@ AC_DEFUN(DEAL_II_CHECK_GETRUSAGE, dnl +dnl ------------------------------------------------------------- +dnl Check if the declared prototype of abort() has a throw() +dnl specification. We overload abort() in our testsuite, so have +dnl to make sure that we match the exception specification +dnl correctly. +dnl +dnl Usage: DEAL_II_CHECK_ABORT +dnl +dnl ------------------------------------------------------------- +AC_DEFUN(DEAL_II_CHECK_ABORT, dnl +[ + AC_MSG_CHECKING([for exception specifications on abort()]) + AC_LANG(C++) + CXXFLAGS="$CXXFLAGSG -Werror" + AC_TRY_COMPILE( + [ +#include +extern "C" void abort () {} + ], + [ + ], + [ + AC_MSG_RESULT(none) + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(DEAL_II_ABORT_NOTHROW_EXCEPTION, 1, + [Defined if the prototype of abort() has a no-throw + exception specification.]) + ]) +] +) + + + + dnl ------------------------------------------------------------- dnl We'd like to use the `isnan' function. On some systems, this is dnl simply declared in (or , for what it's worth), but @@ -3292,80 +3328,6 @@ using namespace std; - -dnl ------------------------------------------------------------ -dnl Check whether some of the HSL functions have been dropped -dnl into their respective place in the contrib subdir. -dnl Check for the following functions to be there: -dnl MA27: needs files ma27.f -dnl MA47: needs files ma47.f ma47.dep -dnl -dnl Usage: DEAL_II_CONFIGURE_HSL -dnl -dnl ------------------------------------------------------------ -AC_DEFUN(DEAL_II_CONFIGURE_HSL, dnl -[ - AC_MSG_CHECKING(for HSL subroutines) - hsl_subroutines="" - if test -r contrib/hsl/source/ma27.f ; then - hsl_subroutines="$hsl_subroutines MA27" - AC_DEFINE(HAVE_HSL_MA27, 1, - [Availability of the MA27 algorithm from HSL]) - fi - - if (test -r contrib/hsl/source/ma47.f && \ - test -r contrib/hsl/source/ma47dep.f) ; then - hsl_subroutines="$hsl_subroutines MA47" - AC_DEFINE(HAVE_HSL_MA47, 1, - [Availability of the MA47 algorithm from HSL]) - fi - - if test "x$hsl_subroutines" != "x" ; then - AC_MSG_RESULT($hsl_subroutines) - USE_CONTRIB_HSL=yes - else - AC_MSG_RESULT(none found) - USE_CONTRIB_HSL=no - fi -]) - - - -dnl ------------------------------------------------------------- -dnl Check for the Tecplot API. If it is found we will be able to write -dnl Tecplot binary files directly. -dnl -dnl This is a little ugly since we aren't guaranteed that TECHOME -dnl will point to the installation directory. It could just as -dnl easily be TEC80HOME, TEC90HOME, etc... So, better check them all -dnl -dnl Usage: DEAL_II_CONFIGURE_TECPLOT -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_CONFIGURE_TECPLOT, dnl -[ - AC_CHECK_FILE($TECHOME/lib/tecio.a, - TECPLOT_LIBRARY_PATH=$TECHOME/lib/tecio.a) - AC_CHECK_FILE($TEC80HOME/lib/tecio.a, - TECPLOT_LIBRARY_PATH=$TEC80HOME/lib/tecio.a) - AC_CHECK_FILE($TEC90HOME/lib/tecio.a, - TECPLOT_LIBRARY_PATH=$TEC90HOME/lib/tecio.a) - AC_CHECK_FILE($TECHOME/include/TECIO.h, - TECPLOT_INCLUDE_PATH=$TECHOME/include) - AC_CHECK_FILE($TEC80HOME/include/TECIO.h, - TECPLOT_INCLUDE_PATH=$TEC80HOME/include) - AC_CHECK_FILE($TEC90HOME/include/TECIO.h, - TECPLOT_INCLUDE_PATH=$TEC90HOME/include) - - if (test -r "$TECPLOT_LIBRARY_PATH" && \ - test -r "$TECPLOT_INCLUDE_PATH/TECIO.h") ; then - AC_DEFINE(DEAL_II_HAVE_TECPLOT, 1, - [Flag indicating whether the library shall be compiled to use the Tecplot interface]) - fi -]) - - - dnl ------------------------------------------------------------- dnl Check whether CXXFLAGSG and CXXFLAGSO are a valid combination dnl of flags or if there are contradicting flags in them. @@ -3488,3 +3450,213 @@ AC_DEFUN(DEAL_II_CHECK_KDOC, dnl AC_MSG_RESULT(using default version $kdocversion) fi ]) + + + +dnl ------------------------------------------------------------- +dnl Check for Doxygen. +dnl +dnl Usage: DEAL_II_CHECK_DOXYGEN +dnl +dnl ------------------------------------------------------------- +AC_DEFUN(DEAL_II_CHECK_DOXYGEN, dnl +[ + AC_ARG_WITH(doxygen, + [ --with-doxygen=filename use 'filename' for doxygen], + DOXYGEN=$withval, + DOXYGEN=) + + dnl lets see whether the file exists + if test "x$DOXYGEN" != "x" ; then + AC_MSG_CHECKING(for specified doxygen path) + if test -r $DOXYGEN ; then + AC_MSG_RESULT($DOXYGEN) + else + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Invalid doxygen path $DOXYGEN) + fi + else + dnl Check doxygen from the regular path. If we can't find it, then + dnl set a flag and come back to that at the end of the ./configure + dnl call. + AC_PATH_PROG(DOXYGEN,doxygen) + if test "x$DOXYGEN" = "x" ; then + doxygen_not_found=yes; + fi + fi +]) + + + +dnl ------------------------------------------------------------ +dnl Check whether some of the HSL functions have been dropped +dnl into their respective place in the contrib subdir. +dnl Check for the following functions to be there: +dnl MA27: needs files ma27.f +dnl MA47: needs files ma47.f ma47.dep +dnl +dnl Usage: DEAL_II_CONFIGURE_HSL +dnl +dnl ------------------------------------------------------------ +AC_DEFUN(DEAL_II_CONFIGURE_HSL, dnl +[ + AC_MSG_CHECKING(for HSL subroutines) + hsl_subroutines="" + if test -r contrib/hsl/source/ma27.f ; then + hsl_subroutines="$hsl_subroutines MA27" + AC_DEFINE(HAVE_HSL_MA27, 1, + [Availability of the MA27 algorithm from HSL]) + fi + + if (test -r contrib/hsl/source/ma47.f && \ + test -r contrib/hsl/source/ma47dep.f) ; then + hsl_subroutines="$hsl_subroutines MA47" + AC_DEFINE(HAVE_HSL_MA47, 1, + [Availability of the MA47 algorithm from HSL]) + fi + + if test "x$hsl_subroutines" != "x" ; then + AC_MSG_RESULT($hsl_subroutines) + USE_CONTRIB_HSL=yes + else + AC_MSG_RESULT(none found) + USE_CONTRIB_HSL=no + fi +]) + + + +dnl ------------------------------------------------------------- +dnl Check for the Tecplot API. If it is found we will be able to write +dnl Tecplot binary files directly. +dnl +dnl This is a little ugly since we aren't guaranteed that TECHOME +dnl will point to the installation directory. It could just as +dnl easily be TEC80HOME, TEC90HOME, etc... So, better check them all +dnl +dnl Usage: DEAL_II_CONFIGURE_TECPLOT +dnl +dnl ------------------------------------------------------------- +AC_DEFUN(DEAL_II_CONFIGURE_TECPLOT, dnl +[ + AC_CHECK_FILE($TECHOME/lib/tecio.a, + TECPLOT_LIBRARY_PATH=$TECHOME/lib/tecio.a) + AC_CHECK_FILE($TEC80HOME/lib/tecio.a, + TECPLOT_LIBRARY_PATH=$TEC80HOME/lib/tecio.a) + AC_CHECK_FILE($TEC90HOME/lib/tecio.a, + TECPLOT_LIBRARY_PATH=$TEC90HOME/lib/tecio.a) + AC_CHECK_FILE($TECHOME/include/TECIO.h, + TECPLOT_INCLUDE_PATH=$TECHOME/include) + AC_CHECK_FILE($TEC80HOME/include/TECIO.h, + TECPLOT_INCLUDE_PATH=$TEC80HOME/include) + AC_CHECK_FILE($TEC90HOME/include/TECIO.h, + TECPLOT_INCLUDE_PATH=$TEC90HOME/include) + + if (test -r "$TECPLOT_LIBRARY_PATH" && \ + test -r "$TECPLOT_INCLUDE_PATH/TECIO.h") ; then + AC_DEFINE(DEAL_II_HAVE_TECPLOT, 1, + [Flag indicating whether the library shall be compiled to use the Tecplot interface]) + fi +]) + + + + +dnl ------------------------------------------------------------ +dnl Check whether PETSc is installed, and if so store the +dnl respective links +dnl +dnl Usage: DEAL_II_CONFIGURE_PETSC +dnl +dnl ------------------------------------------------------------ +AC_DEFUN(DEAL_II_CONFIGURE_PETSC, dnl +[ + dnl First check for the PETSc directory + AC_MSG_CHECKING(for PETSc library directory) + + AC_ARG_WITH(petsc, + [ --with-petsc=/path/to/petsc Specify the path to the PETSc installation, + of which the include and library directories + are subdirs; use this if you want to + override the PETSC_DIR environment variable], + [ + USE_CONTRIB_PETSC=yes + DEAL_II_PETSC_DIR=$withval + AC_MSG_RESULT($DEAL_II_PETSC_DIR) + + dnl Make sure that what was specified is actually correct + if test ! -d $DEAL_II_PETSC_DIR/include \ + -o ! -d $DEAL_II_PETSC_DIR/lib ; then + AC_MSG_ERROR([Path to PETSc specified with --with-petsc does not + point to a complete PETSc installation]) + fi + ], + [ + dnl Take something from the environment variables, if it is there + if test "x$PETSC_DIR" != "x" ; then + USE_CONTRIB_PETSC=yes + DEAL_II_PETSC_DIR="$PETSC_DIR" + AC_MSG_RESULT($DEAL_II_PETSC_DIR) + + dnl Make sure that what this is actually correct + if test ! -d $DEAL_II_PETSC_DIR/include \ + -o ! -d $DEAL_II_PETSC_DIR/lib ; then + AC_MSG_ERROR([The path to PETSc specified in the PETSC_DIR + environment variable does not + point to a complete PETSc installation]) + fi + else + USE_CONTRIB_PETSC=no + DEAL_II_PETSC_DIR="" + AC_MSG_RESULT(not found) + fi + ]) + if test "$USE_CONTRIB_PETSC" = "yes" ; then + AC_DEFINE(DEAL_II_USE_PETSC, 1, + [Defined if a PETSc installation was found and is going + to be used]) + fi + + + dnl Secondly, check for the PETSc architecture, since that determines + dnl where object and configuration files will be found. Do so only + dnl if we are interested in this information at all. + if test "x$USE_CONTRIB_PETSC" != "x" ; then + AC_MSG_CHECKING(for PETSc library architecture) + + AC_ARG_WITH(petsc-arch, + [ --with-petsc-arch=architecture Specify the architecture for your PETSc + installation; use this if you want to + override the PETSC_ARCH environment + variable], + [ + DEAL_II_PETSC_ARCH=$withval + AC_MSG_RESULT($DEAL_II_PETSC_ARCH) + + dnl Make sure that what was specified is actually correct + if test ! -d $DEAL_II_PETSC_DIR/lib/libg_c++/$DEAL_II_PETSC_ARCH \ + ; then + AC_MSG_ERROR([PETSc has not been compiled for the architecture + specified with --with-petsc-arch]) + fi + ], + [ + dnl Take something from the environment variables, if it is there + if test "x$PETSC_ARCH" != "x" ; then + DEAL_II_PETSC_ARCH="$PETSC_ARCH" + AC_MSG_RESULT($DEAL_II_PETSC_ARCH) + + dnl Make sure that what this is actually correct + if test ! -d $DEAL_II_PETSC_DIR/lib/libg_c++/$DEAL_II_PETSC_ARCH \ + ; then + AC_MSG_ERROR([PETSc has not been compiled for the architecture + specified in the PETSC_ARCH environment variable]) + fi + else + AC_MSG_ERROR([If PETSc is used, you must specify the architectur + either through the PETSC_ARCH environment variable, + or through the --with-petsc-arch flag]) + fi + ]) + fi +]) diff --git a/deal.II/base/include/base/config.h.in b/deal.II/base/include/base/config.h.in index 68e1588343..a06e7f34e2 100644 --- a/deal.II/base/include/base/config.h.in +++ b/deal.II/base/include/base/config.h.in @@ -31,6 +31,10 @@ +/* Defined if the prototype of abort() has a no-throw exception specification. + */ +#undef DEAL_II_ABORT_NOTHROW_EXCEPTION + /* Defined if the compiler needs to see the static keyword even for functions in anonymous namespaces, to avoid duplicate symbol errors when linking. For the details, look at aclocal.m4 in the top-level directory. */ @@ -168,6 +172,9 @@ functionality is available. */ #undef DEAL_II_USE_MT_POSIX_NO_BARRIERS +/* Defined if a PETSc installation was found and is going to be used */ +#undef DEAL_II_USE_PETSC + /* Enable the multigrid components of the library */ #undef ENABLE_MULTIGRID @@ -242,11 +249,11 @@ * here to make them unconditionally available to all other parts of the * library. * - * The constants defined here are a subset of the @p{M_XXX} constants sometimes - * declared in the system include file @p{math.h}, but without the - * prefix @p{M_}. + * The constants defined here are a subset of the M_XXX constants + * sometimes declared in the system include file math.h, but without + * the prefix M_. * - * In addition to that, we declare @p{invalid_unsigned_int} to be the + * In addition to that, we declare invalid_unsigned_int to be the * largest unsigned integer representable; this value is widely used in * the library as a marker for an invalid index, an invalid size of an * array, and similar purposes. diff --git a/deal.II/common/Make.global_options.in b/deal.II/common/Make.global_options.in index 406bab9a3a..8b298d1d92 100644 --- a/deal.II/common/Make.global_options.in +++ b/deal.II/common/Make.global_options.in @@ -41,6 +41,9 @@ enable-shared = @enableshared@ DEAL_II_MAJOR = @DEAL_II_MAJOR@ DEAL_II_MINOR = @DEAL_II_MINOR@ USE_CONTRIB_HSL = @USE_CONTRIB_HSL@ +USE_CONTRIB_PETSC = @USE_CONTRIB_PETSC@ +DEAL_II_PETSC_DIR = @DEAL_II_PETSC_DIR@ +DEAL_II_PETSC_ARCH = @DEAL_II_PETSC_ARCH@ TECIO_INCLUDE = @TECPLOT_INCLUDE_PATH@ TECIO_LIBRARY = @TECPLOT_LIBRARY_PATH@ TARGET = @target@ @@ -59,11 +62,10 @@ LIBS += $(TECIO_LIBRARY) # path for libraries -LIBPATH += $(addprefix -L,$(libdir)) +LIBPATH += $(addprefix -L,$(LIBDIR)) -# add search path for libraries for make dependencies - +# add search path for libraries to make dependencies vpath %.a $(libdir) vpath %.so $(libdir) @@ -89,6 +91,20 @@ lib-deal2-3d.g = $(LIBDIR)/libdeal_II_3d.g$(lib-suffix) lib-contrib-hsl = $(LIBDIR)/libhsl$(lib-suffix) +# since the PETSc libs are called the same for both debug and +# optimized mode, we have to have a trick to let the executable +# know which ones are the right (since apparently LD_LIBRARY_PATH +# can't do the trick unless you want to reset it every time +# you switch from debug to optimized mode). To avoid messing with +# -Wl,-rpath in our linker flags, we create one convenience library +# for all PETSc libraries in our own lib directory, and have this one +# twiddle with whatever is necessary to link in PETSc. +lib-contrib-petsc-path.g = $(DEAL_II_PETSC_DIR)/lib/libg_c++/$(DEAL_II_PETSC_ARCH) +lib-contrib-petsc-path.o = $(DEAL_II_PETSC_DIR)/lib/libO_c++/$(DEAL_II_PETSC_ARCH) +lib-contrib-petsc.g = $(LIBDIR)/libpetsc_g$(lib-suffix) +lib-contrib-petsc.o = $(LIBDIR)/libpetsc_o$(lib-suffix) + + # if HSL is used, always link it in conjunction with liblac ifeq ($(USE_CONTRIB_HSL),yes) lib-lac.g += $(lib-contrib-hsl) @@ -96,6 +112,14 @@ ifeq ($(USE_CONTRIB_HSL),yes) endif +# if PETSC is used, we need to add a number of libraries to what +# we link for LAC +ifeq ($(USE_CONTRIB_PETSC),yes) + lib-lac.g += $(lib-contrib-petsc.g) + lib-lac.o += $(lib-contrib-petsc.o) +endif + + # include paths. do not take into account a possibly existing # environment variable, since the compiler will evaluate the value of # that anyway at compile time @@ -106,7 +130,9 @@ include-path-deal2 = $D/deal.II/include include-path-contrib-hsl = $D/contrib/hsl/include include-path-contrib-boost = $D/contrib/boost/include include-path-tecplot = $(TECIO_INCLUDE) - +include-path-petsc = $(DEAL_II_PETSC_DIR)/include +include-path-petsc-bmake = $(DEAL_II_PETSC_DIR)/bmake/$(DEAL_II_PETSC_ARCH) +include-path-petsc-mpi = $(DEAL_II_PETSC_DIR)/src/sys/src/mpiuni INCLUDE = $(addprefix -I, $(include-path-base) \ $(include-path-lac) \ @@ -115,6 +141,12 @@ INCLUDE = $(addprefix -I, $(include-path-base) \ $(include-path-contrib-boost)\ $(include-path-tecplot)) +# add PETSc include path if necessary +ifeq ($(USE_CONTRIB_PETSC),yes) + INCLUDE += -I$(include-path-petsc) -I$(include-path-petsc-bmake)\ + -I$(include-path-petsc-mpi) +endif + # compiler flags for debug and optimized mode CXXFLAGS.g = @DEFS@ @CXXFLAGSG@ $(INCLUDE) CXXFLAGS.o = @DEFS@ @CXXFLAGSO@ $(INCLUDE) @@ -131,3 +163,11 @@ ifeq ($(enable-shared),yes) LDFLAGS += @LDFLAGSPIC@ endif + + +# PETSc wants to see a whole lot of other flags being passed. ... +ifeq ($(USE_CONTRIB_PETSC),yes) + include $(DEAL_II_PETSC_DIR)/bmake/$(DEAL_II_PETSC_ARCH)/variables + CXXFLAGS.g += $(GCXX_PETSCFLAGS) + CXXFLAGS.g += $(OCXX_PETSCFLAGS) +endif diff --git a/deal.II/configure b/deal.II/configure index edfa1cfb80..8ee4f332f4 100755 --- a/deal.II/configure +++ b/deal.II/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.161 . +# From configure.in Revision. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57. # @@ -273,7 +273,7 @@ PACKAGE_BUGREPORT= ac_unique_file="deal.II" ac_subdirs_all="$ac_subdirs_all contrib tests" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DEAL_II_VERSION DEAL_II_MAJOR DEAL_II_MINOR DEAL_II_PATH DEAL2_DIR build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GXX_VERSION CXXFLAGSG CXXFLAGSO CXXFLAGSPIC SHLIBLD LDFLAGSPIC enablemultithreading withmultithreading F77 F77_VERSION F77FLAGSO F77FLAGSG F77FLAGSPIC F77LIBS enableshared lib_suffix AR RANLIB ac_ct_RANLIB enablemultigrid TECPLOT_LIBRARY_PATH TECPLOT_INCLUDE_PATH USE_CONTRIB_HSL kdocdir kdocversion PERL subdirs LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DEAL_II_VERSION DEAL_II_MAJOR DEAL_II_MINOR DEAL_II_PATH DEAL2_DIR build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GXX_VERSION CXXFLAGSG CXXFLAGSO CXXFLAGSPIC SHLIBLD LDFLAGSPIC enablemultithreading withmultithreading F77 F77_VERSION F77FLAGSO F77FLAGSG F77FLAGSPIC F77LIBS enableshared lib_suffix AR RANLIB ac_ct_RANLIB enablemultigrid TECPLOT_LIBRARY_PATH TECPLOT_INCLUDE_PATH USE_CONTRIB_HSL USE_CONTRIB_PETSC DEAL_II_PETSC_DIR DEAL_II_PETSC_ARCH kdocdir kdocversion DOXYGEN PERL subdirs LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -825,10 +825,19 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-multithreading=name If name==posix, or no name given, then use POSIX threads + --with-petsc=/path/to/petsc Specify the path to the PETSc installation, + of which the include and library directories + are subdirs; use this if you want to + override the PETSC_DIR environment variable + --with-petsc-arch=architecture Specify the architecture for your PETSc + installation; use this if you want to + override the PETSC_ARCH environment + variable --with-cpu=cpu Optimize specifically for the given CPU type, rather than just generating code for this processor family --with-kdoc=DIR use kdoc installed in DIR + --with-doxygen=filename use 'filename' for doxygen Some influential environment variables: CC C compiler command @@ -3076,12 +3085,12 @@ rm -f conftest.$ac_objext conftest.$ac_ext ;; MIPSpro*) - CXXFLAGSG="$CXXFLAGS -DDEBUG -no_auto_include -ansiW -woff 1429,1066,1485" - CXXFLAGSO="$CXXFLAGS -O2 -no_auto_include -woff 1174,1552" - LDFLAGS="$LDFLAGS -quiet_prelink" - LIBS="$LIBS -lm" + CXXFLAGSG="$CXXFLAGS -DDEBUG -no_auto_include -ansiW -woff 1429,1066,1485" + CXXFLAGSO="$CXXFLAGS -O2 -no_auto_include -woff 1174,1552" CXXFLAGSPIC="-KPIC" LDFLAGSPIC="-KPIC" + LDFLAGS="$LDFLAGS -quiet_prelink" + LIBS="$LIBS -lm" ;; intel_icc*) @@ -6047,6 +6056,69 @@ rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext fi + echo "$as_me:$LINENO: checking for exception specifications on abort()" >&5 +echo $ECHO_N "checking for exception specifications on abort()... $ECHO_C" >&6 + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + CXXFLAGS="$CXXFLAGSG -Werror" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +extern "C" void abort () {} + +int +main () +{ + + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define DEAL_II_ABORT_NOTHROW_EXCEPTION 1 +_ACEOF + + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + + + echo "$as_me:$LINENO: checking whether getrusage is properly declared" >&5 echo $ECHO_N "checking whether getrusage is properly declared... $ECHO_C" >&6 ac_ext=cc @@ -7542,6 +7614,117 @@ echo "${ECHO_T}none found" >&6 + echo "$as_me:$LINENO: checking for PETSc library directory" >&5 +echo $ECHO_N "checking for PETSc library directory... $ECHO_C" >&6 + + +# Check whether --with-petsc or --without-petsc was given. +if test "${with_petsc+set}" = set; then + withval="$with_petsc" + + USE_CONTRIB_PETSC=yes + DEAL_II_PETSC_DIR=$withval + echo "$as_me:$LINENO: result: $DEAL_II_PETSC_DIR" >&5 +echo "${ECHO_T}$DEAL_II_PETSC_DIR" >&6 + + if test ! -d $DEAL_II_PETSC_DIR/include \ + -o ! -d $DEAL_II_PETSC_DIR/lib ; then + { { echo "$as_me:$LINENO: error: Path to PETSc specified with --with-petsc does not + point to a complete PETSc installation" >&5 +echo "$as_me: error: Path to PETSc specified with --with-petsc does not + point to a complete PETSc installation" >&2;} + { (exit 1); exit 1; }; } + fi + +else + + if test "x$PETSC_DIR" != "x" ; then + USE_CONTRIB_PETSC=yes + DEAL_II_PETSC_DIR="$PETSC_DIR" + echo "$as_me:$LINENO: result: $DEAL_II_PETSC_DIR" >&5 +echo "${ECHO_T}$DEAL_II_PETSC_DIR" >&6 + + if test ! -d $DEAL_II_PETSC_DIR/include \ + -o ! -d $DEAL_II_PETSC_DIR/lib ; then + { { echo "$as_me:$LINENO: error: The path to PETSc specified in the PETSC_DIR + environment variable does not + point to a complete PETSc installation" >&5 +echo "$as_me: error: The path to PETSc specified in the PETSC_DIR + environment variable does not + point to a complete PETSc installation" >&2;} + { (exit 1); exit 1; }; } + fi + else + USE_CONTRIB_PETSC=no + DEAL_II_PETSC_DIR="" + echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}not found" >&6 + fi + +fi; + if test "$USE_CONTRIB_PETSC" = "yes" ; then + +cat >>confdefs.h <<\_ACEOF +#define DEAL_II_USE_PETSC 1 +_ACEOF + + fi + + + if test "x$USE_CONTRIB_PETSC" != "x" ; then + echo "$as_me:$LINENO: checking for PETSc library architecture" >&5 +echo $ECHO_N "checking for PETSc library architecture... $ECHO_C" >&6 + + +# Check whether --with-petsc-arch or --without-petsc-arch was given. +if test "${with_petsc_arch+set}" = set; then + withval="$with_petsc_arch" + + DEAL_II_PETSC_ARCH=$withval + echo "$as_me:$LINENO: result: $DEAL_II_PETSC_ARCH" >&5 +echo "${ECHO_T}$DEAL_II_PETSC_ARCH" >&6 + + if test ! -d $DEAL_II_PETSC_DIR/lib/libg_c++/$DEAL_II_PETSC_ARCH \ + ; then + { { echo "$as_me:$LINENO: error: PETSc has not been compiled for the architecture + specified with --with-petsc-arch" >&5 +echo "$as_me: error: PETSc has not been compiled for the architecture + specified with --with-petsc-arch" >&2;} + { (exit 1); exit 1; }; } + fi + +else + + if test "x$PETSC_ARCH" != "x" ; then + DEAL_II_PETSC_ARCH="$PETSC_ARCH" + echo "$as_me:$LINENO: result: $DEAL_II_PETSC_ARCH" >&5 +echo "${ECHO_T}$DEAL_II_PETSC_ARCH" >&6 + + if test ! -d $DEAL_II_PETSC_DIR/lib/libg_c++/$DEAL_II_PETSC_ARCH \ + ; then + { { echo "$as_me:$LINENO: error: PETSc has not been compiled for the architecture + specified in the PETSC_ARCH environment variable" >&5 +echo "$as_me: error: PETSc has not been compiled for the architecture + specified in the PETSC_ARCH environment variable" >&2;} + { (exit 1); exit 1; }; } + fi + else + { { echo "$as_me:$LINENO: error: If PETSc is used, you must specify the architectur + either through the PETSC_ARCH environment variable, + or through the --with-petsc-arch flag" >&5 +echo "$as_me: error: If PETSc is used, you must specify the architectur + either through the PETSC_ARCH environment variable, + or through the --with-petsc-arch flag" >&2;} + { (exit 1); exit 1; }; } + fi + +fi; + fi + + + + + @@ -7744,6 +7927,76 @@ echo "${ECHO_T}using default version $kdocversion" >&6 + + +# Check whether --with-doxygen or --without-doxygen was given. +if test "${with_doxygen+set}" = set; then + withval="$with_doxygen" + DOXYGEN=$withval +else + DOXYGEN= +fi; + + if test "x$DOXYGEN" != "x" ; then + echo "$as_me:$LINENO: checking for specified doxygen path" >&5 +echo $ECHO_N "checking for specified doxygen path... $ECHO_C" >&6 + if test -r $DOXYGEN ; then + echo "$as_me:$LINENO: result: $DOXYGEN" >&5 +echo "${ECHO_T}$DOXYGEN" >&6 + else + echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}not found" >&6 + { { echo "$as_me:$LINENO: error: Invalid doxygen path $DOXYGEN" >&5 +echo "$as_me: error: Invalid doxygen path $DOXYGEN" >&2;} + { (exit 1); exit 1; }; } + fi + else + # Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_DOXYGEN+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +DOXYGEN=$ac_cv_path_DOXYGEN + +if test -n "$DOXYGEN"; then + echo "$as_me:$LINENO: result: $DOXYGEN" >&5 +echo "${ECHO_T}$DOXYGEN" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + if test "x$DOXYGEN" = "x" ; then + doxygen_not_found=yes; + fi + fi + + + # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 @@ -7810,7 +8063,7 @@ echo "${ECHO_T}--------------------- generating output ---------------------" >& - ac_config_files="$ac_config_files common/Make.global_options common/Makefile.template common/scripts/make_dependencies.pl doc/Makefile doc/auto/Makefile doc/auto/kdoc/Makefile doc/doxygen/options.dox" + ac_config_files="$ac_config_files common/Make.global_options common/Makefile.template common/scripts/make_dependencies.pl doc/Makefile doc/auto/Makefile doc/auto/kdoc/Makefile doc/doxygen/Makefile doc/doxygen/options.dox" test "x$prefix" = xNONE && prefix=$ac_default_prefix @@ -8287,6 +8540,7 @@ do "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/auto/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/auto/Makefile" ;; "doc/auto/kdoc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/auto/kdoc/Makefile" ;; + "doc/doxygen/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/doxygen/Makefile" ;; "doc/doxygen/options.dox" ) CONFIG_FILES="$CONFIG_FILES doc/doxygen/options.dox" ;; "base/include/base/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS base/include/base/config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 @@ -8423,8 +8677,12 @@ s,@enablemultigrid@,$enablemultigrid,;t t s,@TECPLOT_LIBRARY_PATH@,$TECPLOT_LIBRARY_PATH,;t t s,@TECPLOT_INCLUDE_PATH@,$TECPLOT_INCLUDE_PATH,;t t s,@USE_CONTRIB_HSL@,$USE_CONTRIB_HSL,;t t +s,@USE_CONTRIB_PETSC@,$USE_CONTRIB_PETSC,;t t +s,@DEAL_II_PETSC_DIR@,$DEAL_II_PETSC_DIR,;t t +s,@DEAL_II_PETSC_ARCH@,$DEAL_II_PETSC_ARCH,;t t s,@kdocdir@,$kdocdir,;t t s,@kdocversion@,$kdocversion,;t t +s,@DOXYGEN@,$DOXYGEN,;t t s,@PERL@,$PERL,;t t s,@subdirs@,$subdirs,;t t s,@LIBOBJS@,$LIBOBJS,;t t @@ -9039,3 +9297,11 @@ echo echo ------------------------------------------------------------- echo +if test "x$doxygen_not_found" = "xyes" ; then + echo " WARNING: During configuration, no version of the doxygen" + echo " WARNING: documentation generation program could be found." + echo " WARNING: You can still use the library, but you won't be" + echo " WARNING: able to generate API documentation locally on" + echo " WARNING: your machine." + echo +fi diff --git a/deal.II/configure.in b/deal.II/configure.in index 011720abd8..8cdcc1f6a6 100644 --- a/deal.II/configure.in +++ b/deal.II/configure.in @@ -192,6 +192,7 @@ DEAL_II_HAVE_STD_IOSFWD_HEADER DEAL_II_HAVE_BUILTIN_EXPECT DEAL_II_HAVE_VERBOSE_TERMINATE DEAL_II_CHECK_MIN_VECTOR_CAPACITY +DEAL_II_CHECK_ABORT DEAL_II_CHECK_GETRUSAGE DEAL_II_CHECK_ISNAN DEAL_II_CHECK_RAND_R @@ -335,6 +336,10 @@ AC_SUBST(TECPLOT_INCLUDE_PATH) DEAL_II_CONFIGURE_HSL AC_SUBST(USE_CONTRIB_HSL) +DEAL_II_CONFIGURE_PETSC +AC_SUBST(USE_CONTRIB_PETSC) +AC_SUBST(DEAL_II_PETSC_DIR) +AC_SUBST(DEAL_II_PETSC_ARCH) @@ -366,6 +371,9 @@ DEAL_II_CHECK_KDOC AC_SUBST(kdocdir) AC_SUBST(kdocversion) +DEAL_II_CHECK_DOXYGEN +AC_SUBST(DOXYGEN) + AC_PATH_PROG(PERL, perl) AC_SUBST(PERL) @@ -433,11 +441,11 @@ AH_BOTTOM( * here to make them unconditionally available to all other parts of the * library. * - * The constants defined here are a subset of the @p{M_XXX} constants sometimes - * declared in the system include file @p{math.h}, but without the - * prefix @p{M_}. + * The constants defined here are a subset of the M_XXX constants + * sometimes declared in the system include file math.h, but without + * the prefix M_. * - * In addition to that, we declare @p{invalid_unsigned_int} to be the + * In addition to that, we declare invalid_unsigned_int to be the * largest unsigned integer representable; this value is widely used in * the library as a marker for an invalid index, an invalid size of an * array, and similar purposes. @@ -522,6 +530,7 @@ AC_OUTPUT([common/Make.global_options doc/Makefile doc/auto/Makefile doc/auto/kdoc/Makefile + doc/doxygen/Makefile doc/doxygen/options.dox]) @@ -537,3 +546,11 @@ echo echo ------------------------------------------------------------- echo +if test "x$doxygen_not_found" = "xyes" ; then + echo " WARNING: During configuration, no version of the doxygen" + echo " WARNING: documentation generation program could be found." + echo " WARNING: You can still use the library, but you won't be" + echo " WARNING: able to generate API documentation locally on" + echo " WARNING: your machine." + echo +fi diff --git a/deal.II/deal.II/include/dofs/dof_accessor.h b/deal.II/deal.II/include/dofs/dof_accessor.h index c008cdb963..3cb1fb02f4 100644 --- a/deal.II/deal.II/include/dofs/dof_accessor.h +++ b/deal.II/deal.II/include/dofs/dof_accessor.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -326,16 +326,16 @@ class DoFObjectAccessor : public DoFAccessor, * function is only callable for * active cells. * - * The input vector may be either - * a @p{Vector}, + * The input vector may be either a + * @p{Vector}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void get_dof_values (const InputVector &values, @@ -364,16 +364,16 @@ class DoFObjectAccessor : public DoFAccessor, * right size before being passed * to this function. * - * The output vector may be either - * a @ref{Vector}@p{}, + * The output vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void set_dof_values (const Vector &local_values, @@ -405,28 +405,33 @@ class DoFObjectAccessor : public DoFAccessor, /** * Distribute a local (cell based) vector * to a global one by mapping the local - * numbering of the degrees of freedom - * to the global one and entering the - * local values into the global vector. + * numbering of the degrees of freedom to + * the global one and entering the local + * values into the global vector. * - * The elements are @em{added} up to - * the elements in the global vector, - * rather than just set, since this is - * usually what one wants. + * The elements are @em{added} up to the + * elements in the global vector, rather + * than just set, since this is usually + * what one wants. */ - void distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const; + template + void + distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const; /** - * This function does much the same as the - * @p{distribute_local_to_global(Vector,Vector)} + * This function does much the same as + * the + * @p{distribute_local_to_global(Vector,Vector)} * function, but operates on matrices * instead of vectors. The sparse matrix * is supposed to have non-zero entry * slots where required. */ - void distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const; + template + void + distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const; /** * Implement the copy operator needed @@ -575,16 +580,16 @@ class DoFObjectAccessor<1, dim> : public DoFAccessor, * function is only callable for active * cells. * - * The input vector may be either - * a @ref{Vector}@p{}, + * The input vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void get_dof_values (const InputVector &values, @@ -612,16 +617,16 @@ class DoFObjectAccessor<1, dim> : public DoFAccessor, * It is assumed that both vectors already * have the right size beforehand. * - * The output vector may be either - * a @ref{Vector}@p{}, + * The output vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void set_dof_values (const Vector &local_values, @@ -639,28 +644,33 @@ class DoFObjectAccessor<1, dim> : public DoFAccessor, /** * Distribute a local (cell based) vector * to a global one by mapping the local - * numbering of the degrees of freedom - * to the global one and entering the - * local values into the global vector. + * numbering of the degrees of freedom to + * the global one and entering the local + * values into the global vector. * - * The elements are @em{added} up to - * the elements in the global vector, - * rather than just set, since this is - * usually what one wants. + * The elements are @em{added} up to the + * elements in the global vector, rather + * than just set, since this is usually + * what one wants. */ - void distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const; + template + void + distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const; /** - * This function does much the same as the - * @p{distribute_local_to_global(Vector,Vector)} + * This function does much the same as + * the + * @p{distribute_local_to_global(Vector,Vector)} * function, but operates on matrices * instead of vectors. The sparse matrix * is supposed to have non-zero entry * slots where required. */ - void distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const; + template + void + distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const; /** * Implement the copy operator needed @@ -762,16 +772,16 @@ class DoFObjectAccessor<2, dim> : public DoFAccessor, * function is only callable for active * cells. * - * The input vector may be either - * a @ref{Vector}@p{}, + * The input vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void get_dof_values (const InputVector &values, @@ -799,16 +809,16 @@ class DoFObjectAccessor<2, dim> : public DoFAccessor, * It is assumed that both vectors already * have the right size beforehand. * - * The output vector may be either - * a @ref{Vector}@p{}, + * The output vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void set_dof_values (const Vector &local_values, @@ -834,28 +844,33 @@ class DoFObjectAccessor<2, dim> : public DoFAccessor, /** * Distribute a local (cell based) vector * to a global one by mapping the local - * numbering of the degrees of freedom - * to the global one and entering the - * local values into the global vector. + * numbering of the degrees of freedom to + * the global one and entering the local + * values into the global vector. * - * The elements are @em{added} up to - * the elements in the global vector, - * rather than just set, since this is - * usually what one wants. + * The elements are @em{added} up to the + * elements in the global vector, rather + * than just set, since this is usually + * what one wants. */ - void distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const; + template + void + distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const; /** - * This function does much the same as the - * @p{distribute_local_to_global(Vector,Vector)} + * This function does much the same as + * the + * @p{distribute_local_to_global(Vector,Vector)} * function, but operates on matrices * instead of vectors. The sparse matrix * is supposed to have non-zero entry * slots where required. */ - void distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const; + template + void + distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const; /** * Implement the copy operator needed @@ -957,16 +972,16 @@ class DoFObjectAccessor<3, dim> : public DoFAccessor, * function is only callable for active * cells. * - * The input vector may be either - * a @ref{Vector}@p{}, + * The input vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void get_dof_values (const InputVector &values, @@ -994,16 +1009,16 @@ class DoFObjectAccessor<3, dim> : public DoFAccessor, * It is assumed that both vectors already * have the right size beforehand. * - * The output vector may be either - * a @ref{Vector}@p{}, + * The output vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void set_dof_values (const Vector &local_values, @@ -1035,28 +1050,33 @@ class DoFObjectAccessor<3, dim> : public DoFAccessor, /** * Distribute a local (cell based) vector * to a global one by mapping the local - * numbering of the degrees of freedom - * to the global one and entering the - * local values into the global vector. + * numbering of the degrees of freedom to + * the global one and entering the local + * values into the global vector. * - * The elements are @em{added} up to - * the elements in the global vector, - * rather than just set, since this is - * usually what one wants. + * The elements are @em{added} up to the + * elements in the global vector, rather + * than just set, since this is usually + * what one wants. */ - void distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const; + template + void + distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const; /** - * This function does much the same as the - * @p{distribute_local_to_global(Vector,Vector)} + * This function does much the same as + * the + * @p{distribute_local_to_global(Vector,Vector)} * function, but operates on matrices * instead of vectors. The sparse matrix * is supposed to have non-zero entry * slots where required. */ - void distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const; + template + void + distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const; /** * Implement the copy operator needed @@ -1296,16 +1316,16 @@ class DoFCellAccessor : public DoFObjectAccessor * cells by the finite element * objects. * - * The output vector may be either - * a @ref{Vector}@p{}, + * The output vector may be either a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, or a - * @ref{BlockVector}@p{<...,double>}. It - * is in the responsibility of - * the caller to assure that the - * types of the numbers stored in - * input and output vectors are - * compatible and with similar - * accuracy. + * @ref{BlockVector}@p{}, or a + * PETSc vector if deal.II is compiled to + * support PETSc. It is in the + * responsibility of the caller to assure + * that the types of the numbers stored + * in input and output vectors are + * compatible and with similar accuracy. */ template void set_dof_values_by_interpolation (const Vector &local_values, diff --git a/deal.II/deal.II/include/dofs/dof_accessor.templates.h b/deal.II/deal.II/include/dofs/dof_accessor.templates.h index 15660819d9..86883afbee 100644 --- a/deal.II/deal.II/include/dofs/dof_accessor.templates.h +++ b/deal.II/deal.II/include/dofs/dof_accessor.templates.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -28,7 +28,8 @@ template -DoFAccessor::DoFAccessor () : +DoFAccessor::DoFAccessor () + : dof_handler(0) { Assert (false, ExcInvalidObject()); @@ -232,6 +233,99 @@ DoFObjectAccessor<1,dim>::child (const unsigned int i) const +template +template +inline +void +DoFObjectAccessor<1, dim>:: +distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.size() == (2*this->get_fe().dofs_per_vertex + + this->get_fe().dofs_per_line), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.size(), + typename BaseClass::ExcVectorDoesNotMatch()); + + const unsigned int n_dofs = local_source.size(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell vector + for (unsigned int j=0; j +template +inline +void +DoFObjectAccessor<1, dim>:: +distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.m() == (2*this->get_fe().dofs_per_vertex + + this->get_fe().dofs_per_line), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (local_source.m() == local_source.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.m(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (global_destination.m() == global_destination.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + + const unsigned int n_dofs = local_source.m(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell matrix + for (unsigned int i=0; i inline void @@ -381,6 +475,101 @@ DoFObjectAccessor<2,dim>::child (const unsigned int i) const +template +template +inline +void +DoFObjectAccessor<2, dim>:: +distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.size() == (4*this->dof_handler->get_fe().dofs_per_vertex + + 4*this->dof_handler->get_fe().dofs_per_line + + this->dof_handler->get_fe().dofs_per_quad), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.size(), + typename BaseClass::ExcVectorDoesNotMatch()); + + const unsigned int n_dofs = local_source.size(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell vector + for (unsigned int j=0; j +template +inline +void +DoFObjectAccessor<2, dim>:: +distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.m() == (4*this->dof_handler->get_fe().dofs_per_vertex + + 4*this->dof_handler->get_fe().dofs_per_line + + this->dof_handler->get_fe().dofs_per_quad), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (local_source.m() == local_source.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.m(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (global_destination.m() == global_destination.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + + const unsigned int n_dofs = local_source.m(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell matrix + for (unsigned int i=0; i inline void @@ -554,6 +743,103 @@ DoFObjectAccessor<3,dim>::child (const unsigned int i) const +template +template +inline +void +DoFObjectAccessor<3, dim>:: +distribute_local_to_global (const Vector &local_source, + OutputVector &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.size() == (8*this->get_fe().dofs_per_vertex + + 12*this->get_fe().dofs_per_line + + 6*this->get_fe().dofs_per_quad + + this->get_fe().dofs_per_hex), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.size(), + typename BaseClass::ExcVectorDoesNotMatch()); + + const unsigned int n_dofs = local_source.size(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell vector + for (unsigned int j=0; j +template +inline +void +DoFObjectAccessor<3, dim>:: +distribute_local_to_global (const FullMatrix &local_source, + OutputMatrix &global_destination) const +{ + // since the exception classes are + // from a template dependent base + // class, we have to fully qualify + // them. to work around more + // trouble, typedef the template + // dependent base class to a + // non-template dependent name and + // use that to specify the + // qualified exception names + typedef DoFAccessor BaseClass; + + Assert (this->dof_handler != 0, + typename BaseClass::ExcInvalidObject()); + Assert (&this->get_fe() != 0, + typename BaseClass::ExcInvalidObject()); + Assert (local_source.m() == (8*this->get_fe().dofs_per_vertex + + 12*this->get_fe().dofs_per_line + + 6*this->get_fe().dofs_per_quad + + this->get_fe().dofs_per_hex), + typename BaseClass::ExcVectorDoesNotMatch()); + Assert (local_source.m() == local_source.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (this->dof_handler->n_dofs() == global_destination.m(), + typename BaseClass::ExcMatrixDoesNotMatch()); + Assert (global_destination.m() == global_destination.n(), + typename BaseClass::ExcMatrixDoesNotMatch()); + + const unsigned int n_dofs = local_source.m(); + +//TODO[WB]: This function could me made more efficient. First, it allocates memory, which could be avoided by passing in another argument as a scratch array. second, the elementwise access is really slow if we use PETSc vectors/matrices. This should be fixed eventually + + // get indices of dofs + std::vector dofs (n_dofs); + get_dof_indices (dofs); + + // distribute cell matrix + for (unsigned int i=0; i void DoFObjectAccessor<3,dim>::copy_from (const DoFObjectAccessor<3,dim> &a) { diff --git a/deal.II/deal.II/include/dofs/dof_constraints.h b/deal.II/deal.II/include/dofs/dof_constraints.h index de2929f3fd..e14179b5bb 100644 --- a/deal.II/deal.II/include/dofs/dof_constraints.h +++ b/deal.II/deal.II/include/dofs/dof_constraints.h @@ -44,7 +44,12 @@ class BlockIndices; * form as $X x = 0$, and this object then describes the matrix $X$. * * The matrix is organized in lines (rows), but only those lines are stored - * where constraints are present. + * where constraints are present. New constraints are added by adding new + * lines using the @ref{add_line} function, and then populating it using the + * @ref{add_entry} function to a given line, or @ref{add_entries} to add more + * than one entry at a time. After all constraints have been added, you need + * to call @ref{close()}, which compresses the storage format and sorts the + * entries. * * Constraint matrices are used to handle hanging nodes and other constrained * degrees of freedom. When building the global system matrix and the right @@ -99,24 +104,54 @@ class BlockIndices; * procedures). * @end{itemize} * - * Usually, the second way is chosen since memory consumption upon construction - * of a second matrix rules out the first possibility. + * Usually, the second way is chosen since memory consumption upon + * construction of a second matrix rules out the first + * possibility. Furthermore, all example programs use this method, and we + * recommend that you use it instead of the first way. * * This class provides two sets of @p{condense} functions: those taking two * arguments refer to the first possibility above, those taking only one do * their job in-place and refer to the second possibility. * + * The condensation functions exist for different argument types. The in-place + * functions (i.e. those following the second way) exist for arguments of type + * @ref{SparsityPattern}, @ref{SparseMatrix} and @ref{BlockSparseMatrix}. Note + * that there are no versions for arguments of type + * @ref{PETScWrappers::SparseMatrix} or any of the other PETSc matrix wrapper + * classes. This is due to the fact that it is relatively hard to get a + * representation of the sparsity structure of PETSc matrices, and to modify + * them; this holds in particular, if the matrix is actually distributed + * across a cluster of computers. If you want to use PETSc matrices, you can + * either copy an already condensed deal.II matrix, or build the PETSc matrix + * in the already condensed form. + * + * + * @section3{Condensing vectors} + * * Condensing vectors works exactly as described above for matrices. Note that * condensation is an idempotent operation, i.e. doing it more than once on a * vector or matrix yields the same result as doing it only once: once an * object has been condensed, further condensation operations don't change it * any more. * + * In contrast to the matrix condensation functions, the vector condensation + * functions exist in variants for PETSc vectors. However, using them is + * typically expensive, and should be avoided. You should use the same + * techniques as mentioned above to avoid their use. + * + * + * @section3{Distributing constraints} + * * After solving the condensed system of equations, the solution vector has to * be redistributed. This is done by the two @p{distribute} function, one * working with two vectors, one working in-place. The operation of * distribution undoes the condensation process in some sense, but it should - * be noted that it is not the inverse operation. + * be noted that it is not the inverse operation. Basically, distribution sets + * the values of the constrained nodes to the value that is computed from the + * constraint given the values of the unconstrained nodes. This is usually + * necessary since the condensed linear systems only describe the equations + * for unconstrained nodes, and constrained nodes need to get their values in + * a second step. * * @author Wolfgang Bangerth, 1998 */ @@ -484,17 +519,18 @@ class ConstraintMatrix : public Subscriptor 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! + * 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. * * The @p{VectorType} may be a * @ref{Vector}@p{}, * @ref{Vector}@p{}, - * @ref{BlockVector}@p{<...>}, or any - * other type having the same - * interface. + * @ref{BlockVector}@p{<...>}, a PETSc + * vector wrapper class, or any other + * type having the same interface. */ template void condense (const VectorType &uncondensed, @@ -502,12 +538,12 @@ class ConstraintMatrix : public Subscriptor /** * Condense the given vector - * in-place. The @p{VectorType} may - * be a @ref{Vector}@p{}, + * in-place. The @p{VectorType} may be a + * @ref{Vector}@p{}, * @ref{Vector}@p{}, - * @ref{BlockVector}@p{<...>}, or any - * other type having the same - * interface. + * @ref{BlockVector}@p{<...>}, a PETSc + * vector wrapper class, or any other + * type having the same interface. */ template void condense (VectorType &vec) const; @@ -529,37 +565,35 @@ class ConstraintMatrix : public Subscriptor * The @p{VectorType} may be a * @ref{Vector}@p{}, * @ref{Vector}@p{}, - * @ref{BlockVector}@p{<...>}, or any - * other type having the same - * interface. + * @ref{BlockVector}@p{<...>}, a PETSc + * 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 - * @ref{Vector}@p{}, + * Re-distribute the elements of the + * vector in-place. The @p{VectorType} + * may be a @ref{Vector}@p{}, * @ref{Vector}@p{}, - * @ref{BlockVector}@p{<...>}, or any - * other type having the same - * interface. + * @ref{BlockVector}@p{<...>}, a PETSc + * vector wrapper class, or any other + * type having the same interface. */ template void distribute (VectorType &vec) const; /** - * Delete hanging nodes in a - * vector. Sets all hanging node - * values to zero. The - * @p{VectorType} may be a + * Delete hanging nodes in a vector. + * Sets all hanging node values to + * zero. The @p{VectorType} may be a * @ref{Vector}@p{}, * @ref{Vector}@p{}, - * @ref{BlockVector}@p{<...>}, or any - * other type having the same - * interface. + * @ref{BlockVector}@p{<...>}, a PETSc + * vector wrapper class, or any other + * type having the same interface. */ template void set_zero (VectorType &vec) const; diff --git a/deal.II/deal.II/include/dofs/dof_tools.h b/deal.II/deal.II/include/dofs/dof_tools.h index cdad522ab0..2f05695365 100644 --- a/deal.II/deal.II/include/dofs/dof_tools.h +++ b/deal.II/deal.II/include/dofs/dof_tools.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -523,23 +523,20 @@ class DoFTools ConstraintMatrix &constraints); /** - * Take a vector of values which - * live on cells (e.g. an error - * per cell) and distribute it to - * the dofs in such a way that a - * finite element field results, - * which can then be further - * processed, e.g. for - * output. You should note that - * the resulting field will not - * be continuous at hanging - * nodes. This can, however, - * easily be arranged by calling - * the appropraite @p{distribute} - * function of a - * @ref{ConstraintMatrix} object - * created for this - * @ref{DoFHandler} object. + * Take a vector of values which live on + * cells (e.g. an error per cell) and + * distribute it to the dofs in such a + * way that a finite element field + * results, which can then be further + * processed, e.g. for output. You should + * note that the resulting field will not + * be continuous at hanging nodes. This + * can, however, easily be arranged by + * calling the appropraite @p{distribute} + * function of a @ref{ConstraintMatrix} + * object created for this + * @ref{DoFHandler} object, after the + * vector has been fully assembled. * * It is assumed that the number * of elements in @p{cell_data} diff --git a/deal.II/deal.II/include/fe/fe_base.h b/deal.II/deal.II/include/fe/fe_base.h index 506aeed069..e684515446 100644 --- a/deal.II/deal.II/include/fe/fe_base.h +++ b/deal.II/deal.II/include/fe/fe_base.h @@ -671,7 +671,8 @@ class FiniteElementBase : public Subscriptor, * function aborts with * @p{ExcProjectionVoid}. */ - const FullMatrix & restrict (const unsigned int child) const; + const FullMatrix & + get_restriction_matrix (const unsigned int child) const; /** * Embedding matrix between grids. @@ -722,37 +723,34 @@ class FiniteElementBase : public Subscriptor, * by calling the * @ref{prolongation_is_implemented()}. */ - const FullMatrix & prolongate (const unsigned int child) const; + const FullMatrix & + get_prolongation_matrix (const unsigned int child) const; /** - * Return whether this element - * implements its prolongation - * matrices. The return value - * also indicates whether a call - * to the @p{prolongate} function - * will generate an error or not. + * Return whether this element implements + * its prolongation matrices. The return + * value also indicates whether a call to + * the @p{get_prolongation_matrix} + * function will generate an error or + * not. * - * This function is mostly here - * in order to allow us to write - * more efficient test programs - * which we run on all kinds of - * weird elements, and for which - * we simply need to exclude - * certain tests in case - * something is not - * implemented. It will in - * general probably not be a - * great help in applications, - * since there is not much one - * can do if one needs these - * features and they are not - * implemented. This function - * could be used to check whether - * a call to @p{prolongate()} - * will succeed; however, one - * then still needs to cope with - * the lack of information this - * just expresses. + * This function is mostly here in order + * to allow us to write more efficient + * test programs which we run on all + * kinds of weird elements, and for which + * we simply need to exclude certain + * tests in case something is not + * implemented. It will in general + * probably not be a great help in + * applications, since there is not much + * one can do if one needs these features + * and they are not implemented. This + * function could be used to check + * whether a call to + * @p{get_prolongation_matrix()} will + * succeed; however, one then still needs + * to cope with the lack of information + * this just expresses. */ bool prolongation_is_implemented () const; @@ -1351,9 +1349,8 @@ class FiniteElementBase : public Subscriptor, protected: /** - * Array of projection - * matrices. See @p{restrict()} - * above. + * Array of projection matrices. See + * @p{get_restriction_matrix} above. * * Matrices in this array are * automatically initialized to @@ -1366,9 +1363,8 @@ class FiniteElementBase : public Subscriptor, FullMatrix restriction[GeometryInfo::children_per_cell]; /** - * Array of embedding - * matrices. See @p{prolongate()} - * above. + * Array of embedding matrices. See + * @p{get_prolongation_matrix()} above. * * Matrices in this array are * automatically initialized to @@ -1706,20 +1702,18 @@ class FiniteElementBase : public Subscriptor, compute_n_nonzero_components (const std::vector > &nonzero_components); /** - * Allow the FESystem class to - * access the restriction and - * prolongation matrices - * directly. Hence, FESystem has - * the possibility to see if - * these matrices are initialized - * without accessing these - * matrices through the - * @p{restrict} and - * @p{prolongate} functions. This - * is important as these - * functions include assertions - * that throw if the matrices are - * not already initialized. + * Allow the FESystem class to access the + * restriction and prolongation matrices + * directly. Hence, FESystem has the + * possibility to see if these matrices + * are initialized without accessing + * these matrices through the + * @p{get_restriction_matrix} and + * @p{get_prolongation_matrix} + * functions. This is important as these + * functions include assertions that + * throw if the matrices are not already + * initialized. */ template friend class FESystem; diff --git a/deal.II/deal.II/include/fe/fe_values.h b/deal.II/deal.II/include/fe/fe_values.h index 2ce14f2eb3..071c5fe86a 100644 --- a/deal.II/deal.II/include/fe/fe_values.h +++ b/deal.II/deal.II/include/fe/fe_values.h @@ -444,15 +444,21 @@ class FEValuesBase : protected FEValuesData * returning a vector of vectors * of results. * + * This function may only be used if the + * finite element in use is a scalar one, + * i.e. has only one vector component. If + * it is a vector-valued one, then use + * the other @p{get_function_values} + * function. + * * The function assumes that the * values object already has the * correct size. * - * The actual data type of the - * input vector may be either a - * Vector, - * Vector, or - * BlockVector. It + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes. It * represents a global vector of * DoF values associated with the * DofHandler object with @@ -473,11 +479,10 @@ class FEValuesBase : protected FEValuesData * applied to multi-component * elements. * - * The actual data type of the - * input vector may be either a - * Vector, - * Vector, or - * BlockVector. It + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes. It * represents a global vector of * DoF values associated with the * DofHandler object with @@ -560,15 +565,21 @@ class FEValuesBase : protected FEValuesData * one the interpolated function values * are returned. * + * This function may only be used if the + * finite element in use is a scalar one, + * i.e. has only one vector component. If + * it is a vector-valued one, then use + * the other @p{get_function_grads} + * function. + * * The function assumes that the * @p{gradients} object already has the * right size. * - * The actual data type of the - * input vector may be either a - * Vector, - * Vector, or - * BlockVector. It + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes. It * represents a global vector of * DoF values associated with the * DofHandler object with @@ -604,11 +615,10 @@ class FEValuesBase : protected FEValuesData * but applied to multi-component * elements. * - * The actual data type of the - * input vector may be either a - * @p{Vector}, - * @p{Vector}, or - * @p{BlockVector}. It + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes. It * represents a global vector of * DoF values associated with the * @ref{DofHandler} object with @@ -702,11 +712,18 @@ class FEValuesBase : protected FEValuesData * @p{second_derivatives} object * already has the correct size. * - * The actual data type of the - * input vector may be either a - * @p{Vector}, - * @p{Vector}, or - * @p{BlockVector}. It + * This function may only be used if the + * finite element in use is a scalar one, + * i.e. has only one vector component. If + * it is a vector-valued one, then use + * the other + * @p{get_function_2nd_derivatives} + * function. + * + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes..It * represents a global vector of * DoF values associated with the * @ref{DofHandler} object with @@ -720,8 +737,9 @@ class FEValuesBase : protected FEValuesData * on the unit cell). */ template - void get_function_2nd_derivatives (const InputVector& fe_function, - std::vector >& second_derivatives) const; + void + get_function_2nd_derivatives (const InputVector& fe_function, + std::vector >& second_derivatives) const; /** @@ -740,11 +758,10 @@ class FEValuesBase : protected FEValuesData * name, but applies to * vector-valued finite elements. * - * The actual data type of the - * input vector may be either a - * @p{Vector}, - * @p{Vector}, or - * @p{BlockVector}. It + * The actual data type of the input + * vector may be either a @p{Vector}, + * @p{BlockVector}, or one of the + * PETSc vector wrapper classes. It * represents a global vector of * DoF values associated with the * @ref{DofHandler} object with @@ -758,8 +775,9 @@ class FEValuesBase : protected FEValuesData * on the unit cell). */ template - void get_function_2nd_derivatives (const InputVector &fe_function, - std::vector > > &second_derivatives) const; + void + get_function_2nd_derivatives (const InputVector &fe_function, + std::vector > > &second_derivatives) const; /** * Position of the @p{i}th diff --git a/deal.II/deal.II/include/grid/grid_refinement.h b/deal.II/deal.II/include/grid/grid_refinement.h index 523b8b744d..d7aeb1bfc0 100644 --- a/deal.II/deal.II/include/grid/grid_refinement.h +++ b/deal.II/deal.II/include/grid/grid_refinement.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -15,9 +15,11 @@ #include -#include +#include + #include + // forward declarations template class Triangulation; template class Vector; @@ -28,13 +30,13 @@ template class Vector; * This class provides several function that flag certain cells for * coarsening or refinement based on a vector of ``error'' * indicators and some selection algorithm. The central function is - * @p{refine (const Vector &criterion, const double threshold)}: + * @p{refine (const Vector &criterion, const double threshold)}: * it takes a vector of values, one per active cell, * which denote the criterion according to which the triangulation * is to be refined. It marks all cells for which the criterion is * greater than the threshold being given as the second * argument. Analogously, - * @p{coarsen (const Vector &criterion, const double threshold)} + * @p{coarsen (const Vector &criterion, const double threshold)} * flags those cells for * coarsening for which the criterion is less than the threshold. * @@ -155,19 +157,11 @@ class GridRefinement * following functions and to the * general doc for this class for * more information. - * - * Note that this function takes - * a vector of @p{float}s, rather - * than the usual @p{double}s, - * since accuracy is not so much - * needed here and saving memory - * may be a good goal when using - * many cells. */ - template - static void refine (Triangulation &tria, - const Vector &criteria, - const double threshold); + template + static void refine (Triangulation &tria, + const Vector &criteria, + const double threshold); /** * Analogue to the @p{refine} @@ -176,19 +170,11 @@ class GridRefinement * absolute value of the * criterion is less than the * given threshold. - * - * Note that this function takes - * a vector of @p{float}s, rather - * than the usual @p{double}s, - * since accuracy is not so much - * needed here and saving memory - * may be a good goal when using - * many cells. */ - template - static void coarsen (Triangulation &tria, - const Vector &criteria, - const double threshold); + template + static void coarsen (Triangulation &tria, + const Vector &criteria, + const double threshold); /** * Refine the triangulation by @@ -208,20 +194,14 @@ class GridRefinement * Refer to the general doc of * this class for more * information. - * - * Note that this function takes - * a vector of @p{float}s, rather - * than the usual @p{double}s, - * since accuracy is not so much - * needed here and saving memory - * may be a good goal when using - * many cells. */ - template - static void refine_and_coarsen_fixed_number (Triangulation &tria, - const Vector &criteria, - const double top_fraction_of_cells, - const double bottom_fraction_of_cells); + template + static + void + refine_and_coarsen_fixed_number (Triangulation &tria, + const Vector &criteria, + const double top_fraction_of_cells, + const double bottom_fraction_of_cells); /** * Refine the triangulation by @@ -241,20 +221,14 @@ class GridRefinement * Refer to the general doc of * this class for more * information. - * - * Note that this function takes - * a vector of @p{float}s, rather - * than the usual @p{double}s, - * since accuracy is not so much - * needed here and saving memory - * may be a good goal when using - * many cells. */ - template - static void refine_and_coarsen_fixed_fraction (Triangulation &tria, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction); + template + static + void + refine_and_coarsen_fixed_fraction (Triangulation &tria, + const Vector &criteria, + const double top_fraction, + const double bottom_fraction); @@ -277,19 +251,13 @@ class GridRefinement * Refer to the general doc of * this class for more * information. - * - * Note that this function takes - * a vector of @p{float}s, rather - * than the usual @p{double}s, - * since accuracy is not so much - * needed here and saving memory - * may be a good goal when using - * many cells. */ - template - static void refine_and_coarsen_optimize (Triangulation &tria, - const Vector &criteria); + template + static + void + refine_and_coarsen_optimize (Triangulation &tria, + const Vector &criteria); /** * Exception @@ -315,11 +283,11 @@ class GridRefinement * STL version and is needed in * @p{refine_and_coarsen_optimize} */ - template - static void qsort_index(const Vector &a, - std::vector &ind, - int l, - int r); + template + static void qsort_index (const Vector &a, + std::vector &ind, + int l, + int r); }; diff --git a/deal.II/deal.II/include/grid/grid_reordering.h b/deal.II/deal.II/include/grid/grid_reordering.h index 6153451658..2472826913 100644 --- a/deal.II/deal.II/include/grid/grid_reordering.h +++ b/deal.II/deal.II/include/grid/grid_reordering.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -422,20 +422,24 @@ * It is obvious that this algorithm has linear run-time, since it * only ever touches each face exactly once. * - * The algorithm just described is implemented in a specialization of - * this class for the 2d case. Note that in principle, it should be - * possible to extend this algorithm to 3d as well, using sheets - * instead of strings of cells to work on. If a grid is reorientable, - * then such an algorithm should be able to do so in linear time; if - * it is not orientable, then it should abort in linear time as - * well. However, this has not yet been implemented. Rather, we use - * the backtracking and branch pruning algorithm for 3d described - * below; this algorithm predates the 2d linear complexity algorithm - * and was initially also used in 2d. + * The algorithm just described is implemented in a specialization of this + * class for the 2d case. A similar, but slightly more complex algorithm is + * implemented in a specialization for 3d. It using sheets instead of strings + * of cells to work on. If a grid is orientable, then the algorithm is able to + * do its work in linear time; if it is not orientable, then it aborts in + * linear time as well. Both algorithms are described in a paper by Agelek, + * Anderson, Bangerth and Barth, see the publications page of the deal.II + * library. * * - * @sect3{The 3d branch reshuffling and pruning algorithm} + * @sect3{For the curious} * + * Prior to the implementation of the algorithms developed by Michael Anderson + * and described above, we used a branch-and-cut algorithm initially + * implemented in 2000 by Wolfgang Bangerth. Although it is no longer used + * here is how it works, and why it doesn't always work for large meshes since + * its run-time can exponential in bad cases. + * * The first observation is that although there are counterexamples, * problems are usually local. For example, in the second example * mentioned above, if we had numbered the cells in a way that diff --git a/deal.II/deal.II/include/multigrid/mg_transfer.templates.h b/deal.II/deal.II/include/multigrid/mg_transfer.templates.h index 8e9d246778..f2e6a3b213 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer.templates.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer.templates.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/deal.II/deal.II/include/numerics/data_out.h b/deal.II/deal.II/include/numerics/data_out.h index 33d0444a50..742ddcb497 100644 --- a/deal.II/deal.II/include/numerics/data_out.h +++ b/deal.II/deal.II/include/numerics/data_out.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -21,7 +21,10 @@ #include #include -template class BlockVector; +#include + + +template class FEValuesBase; /** @@ -41,13 +44,11 @@ template class BlockVector; * way: * @begin{verbatim} * ... - * ... // compute solution, which is of type Vector - * ... // and contains nodal values + * ... // compute solution, which contains nodal values * ... - * ... // compute error_estimator, which is of type Vector - * ... // and contains one value per cell + * ... // compute error_estimator, which contains one value per cell * - * vector solution_names; + * std::vector solution_names; * solution_names.push_back ("x-displacement"); * solution_names.push_back ("y-displacement"); * @@ -272,10 +273,11 @@ class DataOut_DoFData : public DataOutInterface * class to see which characters * are valid and which are not. * - * The actual type for the - * template argument may only be - * either @p{Vector} or - * @p{BlockVector}. + * The actual type for the template + * argument may be any vector type from + * which @ref{FEValue} can extract values + * on a cell using the + * @p{get_function_values} function. */ template void add_data_vector (const VECTOR &data, @@ -306,10 +308,11 @@ class DataOut_DoFData : public DataOutInterface * underscore and the number of * each component to @p{name} * - * The actual type for the - * template argument may only be - * either @p{Vector} or - * @p{BlockVector}. + * The actual type for the template + * argument may be any vector type from + * which @ref{FEValue} can extract values + * on a cell using the + * @p{get_function_values} function. */ template void add_data_vector (const VECTOR &data, @@ -477,66 +480,173 @@ class DataOut_DoFData : public DataOutInterface protected: /** - * Declare an entry in the list of - * data elements. + * For each vector that has been added + * through the @ref{add_data_vector} + * functions, we need to keep track of a + * pointer to it, and allow data + * extraction from it when we generate + * patches. Unfortunately, we need to do + * this for a number of different vector + * types. Fortunately, they all have the + * same interface. So the way we go is to + * have a base class that provides the + * functions to access the vector's + * information, and to have a derived + * template class that can be + * instantiated for each vector + * type. Since the vectors all have the + * same interface, this is no big + * problem, as they can all use the same + * general templatized code. + * + * @author Wolfgang Bangerth, 2004 */ - struct DataEntry + class DataEntryBase { + public: /** - * Constructor. If no - * arguments are given, an - * invalid object is - * constructed (we need a - * constructor with no - * explicit arguments for STL - * classes). + * Constructor. Give a list of names + * for the individual components of + * the vector. */ - DataEntry (const Vector *data = 0, - const std::vector &names = std::vector()); + DataEntryBase (const std::vector &names); - /** - * Constructor for block vector data. - */ - DataEntry (const BlockVector *data, - const std::vector &names = std::vector()); + /** + * Destructor made virtual. + */ + virtual ~DataEntryBase (); + + /** + * Assuming that the stored vector is + * a cell vector, extract the given + * element from it. + */ + virtual + double + get_cell_data_value (const unsigned int cell_number) const = 0; + + /** + * Given a @p{FEValuesBase} object, + * extract the values on the present + * cell from the vector we actually + * store. + */ + virtual + void + get_function_values (const FEValuesBase &fe_patch_values, + std::vector &patch_values) const = 0; + + /** + * Given a @p{FEValuesBase} object, + * extract the values on the present + * cell from the vector we actually + * store. This function does the same + * as the one above but for + * vector-valued finite elements. + */ + virtual + void + get_function_values (const FEValuesBase &fe_patch_values, + std::vector > &patch_values_system) const = 0; + /** + * Clear all references to the + * vectors. + */ + virtual void clear () = 0; + /** * Determine an estimate for * the memory consumption (in * bytes) of this object. */ - unsigned int memory_consumption () const; - + virtual unsigned int memory_consumption () const = 0; + /** - * Pointer to the data - * vector. Note that - * ownership of the vector - * pointed to remains with - * the caller of this class. + * Names of the components of this + * data vector. */ - const Vector *single_data; + std::vector names; + }; + + + /** + * Class that stores a pointer to a + * vector of type equal to the template + * argument, and provides the functions + * to extract data from it. + * + * @author Wolfgang Bangerth, 2004 + */ + template + class DataEntry : public DataEntryBase + { + public: + /** + * Constructor. Give a pointer to a + * vector and the list of names for + * the individual components. + */ + DataEntry (const VectorType *data, + const std::vector &names); /** - * Pointer to a block vector of - * data. Either this pointer - * or the previous is used, - * depending on the stored - * vector type. + * Assuming that the stored vector is + * a cell vector, extract the given + * element from it. */ - const BlockVector* block_data; + virtual + double + get_cell_data_value (const unsigned int cell_number) const; /** - * True if stored vector is a - * block vector. + * Given a @p{FEValuesBase} object, + * extract the values on the present + * cell from the vector we actually + * store. + */ + virtual + void + get_function_values (const FEValuesBase &fe_patch_values, + std::vector &patch_values) const; + + /** + * Given a @p{FEValuesBase} object, + * extract the values on the present + * cell from the vector we actually + * store. This function does the same + * as the one above but for + * vector-valued finite elements. */ - bool has_block; + virtual + void + get_function_values (const FEValuesBase &fe_patch_values, + std::vector > &patch_values_system) const; + /** + * Clear all references to the + * vectors. + */ + virtual void clear (); + /** - * Names of the components of this - * data vector. + * Determine an estimate for + * the memory consumption (in + * bytes) of this object. */ - std::vector names; + virtual unsigned int memory_consumption () const; + + private: + /** + * Pointer to the data + * vector. Note that + * ownership of the vector + * pointed to remains with + * the caller of this class. + */ + const VectorType *vector; }; + /** * Abbreviate the somewhat lengthy @@ -553,13 +663,13 @@ class DataOut_DoFData : public DataOutInterface * List of data elements with vectors of * values for each degree of freedom. */ - std::vector dof_data; + std::vector > dof_data; /** * List of data elements with vectors of * values for each cell. */ - std::vector cell_data; + std::vector > cell_data; /** * This is a list of patches that is diff --git a/deal.II/deal.II/include/numerics/error_estimator.h b/deal.II/deal.II/include/numerics/error_estimator.h index bcff513f79..d2ff000c1a 100644 --- a/deal.II/deal.II/include/numerics/error_estimator.h +++ b/deal.II/deal.II/include/numerics/error_estimator.h @@ -259,11 +259,12 @@ class KellyErrorEstimator * implemented in two and three * dimensions. */ + template static void estimate (const Mapping &mapping, const DoFHandler &dof, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const Vector &solution, + const InputVector &solution, Vector &error, const std::vector &component_mask = std::vector(), const Function *coefficients = 0, @@ -274,10 +275,11 @@ class KellyErrorEstimator * function, see above, with * @p{mapping=MappingQ1()}. */ + template static void estimate (const DoFHandler &dof, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const Vector &solution, + const InputVector &solution, Vector &error, const std::vector &component_mask = std::vector(), const Function *coefficients = 0, @@ -310,11 +312,12 @@ class KellyErrorEstimator * references, so we had to use a * vector of pointers.) */ + template static void estimate (const Mapping &mapping, const DoFHandler &dof, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, std::vector*> &errors, const std::vector &component_mask = std::vector(), const Function *coefficients = 0, @@ -324,11 +327,12 @@ class KellyErrorEstimator * Calls the @p{estimate} * function, see above, with * @p{mapping=MappingQ1()}. - */ + */ + template static void estimate (const DoFHandler &dof, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, std::vector*> &errors, const std::vector &component_mask = std::vector(), const Function *coefficients = 0, @@ -526,11 +530,12 @@ class KellyErrorEstimator * dimension is implemented * seperatly. */ + template static void estimate_some (const Mapping &mapping, const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, const std::pair this_thread, @@ -557,12 +562,13 @@ class KellyErrorEstimator * ending up with a function of * 500 lines of code. */ + template static void integrate_over_regular_face (const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, FaceIntegrals &face_integrals, @@ -583,11 +589,12 @@ class KellyErrorEstimator * integration is a bit more * complex. */ + template static void integrate_over_irregular_face (const DoFHandler &dof_handler, const Quadrature &quadrature, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, FaceIntegrals &face_integrals, @@ -614,60 +621,5 @@ class KellyErrorEstimator }; -/* -------------- declaration of explicit specializations ------------- */ - -/// @if NoDoc - -template <> void KellyErrorEstimator<1>::estimate_some ( - const Mapping<1> &mapping, - const DoFHandler<1> &dof_handler, - const Quadrature<0> &quadrature, - const FunctionMap<1>::type &neumann_bc, - const std::vector*> &solutions, - const std::vector &component_mask, - const Function<1> *coefficients, - const std::pair this_thread, - FaceIntegrals &face_integrals, - PerThreadData &per_thread_data); - -template <> void KellyErrorEstimator<1>::estimate ( - const Mapping<1> &mapping, - const DoFHandler<1> &dof_handler, - const Quadrature<0> &, - const FunctionMap<1>::type &neumann_bc, - const std::vector*> &solutions, - std::vector*> &errors, - const std::vector &component_mask_, - const Function<1> *coefficient, - const unsigned int); - -template <> void KellyErrorEstimator<1>::integrate_over_regular_face ( - const DoFHandler<1> &dof_handler, - const Quadrature<0> &quadrature, - const FunctionMap<1>::type &neumann_bc, - const std::vector*> &solutions, - const std::vector &component_mask, - const Function<1> *coefficients, - FaceIntegrals &face_integrals, - PerThreadData &, - const active_cell_iterator &, - const unsigned int , - FEFaceValues<1> &, - FEFaceValues<1> &); - -template <> void KellyErrorEstimator<1>::integrate_over_irregular_face ( - const DoFHandler<1> &dof_handler, - const Quadrature<0> &quadrature, - const std::vector*> &solutions, - const std::vector &component_mask, - const Function<1> *coefficients, - FaceIntegrals &face_integrals, - PerThreadData &, - const active_cell_iterator &, - const unsigned int , - FEFaceValues<1> &, - FESubfaceValues<1> &); - -/// @endif #endif diff --git a/deal.II/deal.II/source/dofs/dof_accessor.cc b/deal.II/deal.II/source/dofs/dof_accessor.cc index 1a6ac31951..c5a852c4ac 100644 --- a/deal.II/deal.II/source/dofs/dof_accessor.cc +++ b/deal.II/deal.II/source/dofs/dof_accessor.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -13,6 +13,7 @@ #include +#include #include #include @@ -82,89 +83,6 @@ void DoFObjectAccessor<1, dim>::set_vertex_dof_index (const unsigned int vertex, -template -void DoFObjectAccessor<1, dim>:: -distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const -{ - // since the exception classes are - // from a template dependent base - // class, we have to fully qualify - // them. to work around more - // trouble, typedef the template - // dependent base class to a - // non-template dependent name and - // use that to specify the - // qualified exception names - typedef DoFAccessor BaseClass; - - Assert (this->dof_handler != 0, - typename BaseClass::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename BaseClass::ExcInvalidObject()); - Assert (local_source.size() == (2*this->dof_handler->get_fe().dofs_per_vertex + - this->dof_handler->get_fe().dofs_per_line), - typename BaseClass::ExcVectorDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.size(), - typename BaseClass::ExcVectorDoesNotMatch()); - - const unsigned int n_dofs = local_source.size(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell vector - for (unsigned int j=0; j -void DoFObjectAccessor<1, dim>:: -distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const -{ - // since the exception classes are - // from a template dependent base - // class, we have to fully qualify - // them. to work around more - // trouble, typedef the template - // dependent base class to a - // non-template dependent name and - // use that to specify the - // qualified exception names - typedef DoFAccessor BaseClass; - - Assert (this->dof_handler != 0, - typename BaseClass::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename BaseClass::ExcInvalidObject()); - Assert (local_source.m() == (2*this->dof_handler->get_fe().dofs_per_vertex + - this->dof_handler->get_fe().dofs_per_line), - typename BaseClass::ExcVectorDoesNotMatch()); - Assert (local_source.m() == local_source.n(), - typename BaseClass::ExcMatrixDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.m(), - typename BaseClass::ExcMatrixDoesNotMatch()); - Assert (global_destination.m() == global_destination.n(), - typename BaseClass::ExcMatrixDoesNotMatch()); - - const unsigned int n_dofs = local_source.m(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell matrix - for (unsigned int i=0; i template void @@ -270,67 +188,6 @@ DoFObjectAccessor<2, dim>::set_vertex_dof_index (const unsigned int vertex, -template -void DoFObjectAccessor<2, dim>:: -distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const { - Assert (this->dof_handler != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (local_source.size() == (4*this->dof_handler->get_fe().dofs_per_vertex + - 4*this->dof_handler->get_fe().dofs_per_line + - this->dof_handler->get_fe().dofs_per_quad), - typename DoFAccessor::ExcVectorDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.size(), - typename DoFAccessor::ExcVectorDoesNotMatch()); - - const unsigned int n_dofs = local_source.size(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell vector - for (unsigned int j=0; j -void DoFObjectAccessor<2, dim>:: -distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const { - Assert (this->dof_handler != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (local_source.m() == (4*this->dof_handler->get_fe().dofs_per_vertex + - 4*this->dof_handler->get_fe().dofs_per_line + - this->dof_handler->get_fe().dofs_per_quad), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (local_source.m() == local_source.n(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.m(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (global_destination.m() == global_destination.n(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - - const unsigned int n_dofs = local_source.m(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell matrix - for (unsigned int i=0; i template void @@ -450,71 +307,6 @@ void DoFObjectAccessor<3, dim>::set_vertex_dof_index (const unsigned int vertex, -template -void DoFObjectAccessor<3, dim>:: -distribute_local_to_global (const Vector &local_source, - Vector &global_destination) const -{ - Assert (this->dof_handler != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (local_source.size() == (8*this->dof_handler->get_fe().dofs_per_vertex + - 12*this->dof_handler->get_fe().dofs_per_line + - 6*this->dof_handler->get_fe().dofs_per_quad + - this->dof_handler->get_fe().dofs_per_hex), - typename DoFAccessor::ExcVectorDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.size(), - typename DoFAccessor::ExcVectorDoesNotMatch()); - - const unsigned int n_dofs = local_source.size(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell vector - for (unsigned int j=0; j -void DoFObjectAccessor<3, dim>:: -distribute_local_to_global (const FullMatrix &local_source, - SparseMatrix &global_destination) const -{ - Assert (this->dof_handler != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (&this->get_fe() != 0, - typename DoFAccessor::ExcInvalidObject()); - Assert (local_source.m() == (8*this->dof_handler->get_fe().dofs_per_vertex + - 12*this->dof_handler->get_fe().dofs_per_line + - 6*this->dof_handler->get_fe().dofs_per_quad + - this->dof_handler->get_fe().dofs_per_hex), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (local_source.m() == local_source.n(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (this->dof_handler->n_dofs() == global_destination.m(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - Assert (global_destination.m() == global_destination.n(), - typename DoFAccessor::ExcMatrixDoesNotMatch()); - - const unsigned int n_dofs = local_source.m(); - - // get indices of dofs - std::vector dofs (n_dofs); - get_dof_indices (dofs); - - // distribute cell matrix - for (unsigned int i=0; i template void @@ -756,7 +548,7 @@ DoFCellAccessor::get_interpolated_dof_values (const InputVector &values, tmp1); // interpolate these to the mother // cell - fe.restrict(child).vmult (tmp2, tmp1); + fe.get_restriction_matrix(child).vmult (tmp2, tmp1); // and add up or set them // in the output vector @@ -803,7 +595,8 @@ DoFCellAccessor::set_dof_values_by_interpolation (const Vector &loc { // prolong the given data // to the present cell - this->dof_handler->get_fe().prolongate(child).vmult (tmp, local_values); + this->dof_handler->get_fe().get_prolongation_matrix(child) + .vmult (tmp, local_values); this->child(child)->set_dof_values_by_interpolation (tmp, values); }; }; @@ -883,6 +676,26 @@ void DoFObjectAccessor<1,deal_II_dimension>::set_dof_values,float> (const Vector&, BlockVector&) const; +// for Petsc vectors +#if DEAL_II_USE_PETSC +template +void +DoFObjectAccessor<1,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<1,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<1,deal_II_dimension>::set_dof_values +(const Vector &, PETScWrappers::Vector&) const; +template +void +DoFObjectAccessor<1,deal_II_dimension>::set_dof_values +(const Vector&, PETScWrappers::Vector&) const; +#endif + #if deal_II_dimension >= 2 template void @@ -952,7 +765,25 @@ void DoFObjectAccessor<2,deal_II_dimension>::set_dof_values,float> (const Vector&, BlockVector&) const; - +// for Petsc vectors +#if DEAL_II_USE_PETSC +template +void +DoFObjectAccessor<2,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<2,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<2,deal_II_dimension>::set_dof_values +(const Vector &, PETScWrappers::Vector&) const; +template +void +DoFObjectAccessor<2,deal_II_dimension>::set_dof_values +(const Vector&, PETScWrappers::Vector&) const; +#endif #endif @@ -1027,7 +858,25 @@ void DoFObjectAccessor<3,deal_II_dimension>::set_dof_values,float> (const Vector&, BlockVector&) const; - +// for Petsc vectors +#if DEAL_II_USE_PETSC +template +void +DoFObjectAccessor<3,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<3,deal_II_dimension>::get_dof_values +(const PETScWrappers::Vector &, Vector&) const; +template +void +DoFObjectAccessor<3,deal_II_dimension>::set_dof_values +(const Vector&, PETScWrappers::Vector &) const; +template +void +DoFObjectAccessor<3,deal_II_dimension>::set_dof_values +(const Vector&, PETScWrappers::Vector&) const; +#endif #endif @@ -1123,6 +972,32 @@ DoFCellAccessor:: set_dof_values_by_interpolation,float> (const Vector&, BlockVector&) const; +// for Petsc vectors +#if DEAL_II_USE_PETSC +template +void +DoFCellAccessor:: +get_interpolated_dof_values +(const PETScWrappers::Vector&, Vector&) const; +template +void +DoFCellAccessor:: +set_dof_values_by_interpolation +(const Vector&, PETScWrappers::Vector&) const; + +template +void +DoFCellAccessor:: +get_interpolated_dof_values +(const PETScWrappers::Vector&, Vector&) const; +template +void +DoFCellAccessor:: +set_dof_values_by_interpolation +(const Vector&, PETScWrappers::Vector&) const; + +#endif + template class DoFAccessor; diff --git a/deal.II/deal.II/source/dofs/dof_constraints.cc b/deal.II/deal.II/source/dofs/dof_constraints.cc index cd402bc6e2..d51dbc3e99 100644 --- a/deal.II/deal.II/source/dofs/dof_constraints.cc +++ b/deal.II/deal.II/source/dofs/dof_constraints.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1250,45 +1251,50 @@ ConstraintMatrix::memory_consumption () const // arg, and putting parentheses around the arg yields incorrect // syntax... -#define vector_functions \ +#define VECTOR_FUNCTIONS(VectorType) \ template void ConstraintMatrix::condense(const VectorType &uncondensed,\ VectorType &condensed) const;\ template void ConstraintMatrix::condense(VectorType &vec) const;\ template void ConstraintMatrix::set_zero(VectorType &vec) const;\ template void ConstraintMatrix::distribute(const VectorType &condensed,\ VectorType &uncondensed) const;\ - template void ConstraintMatrix::distribute(VectorType &vec) const; + template void ConstraintMatrix::distribute(VectorType &vec) const +VECTOR_FUNCTIONS(Vector); +VECTOR_FUNCTIONS(Vector); +VECTOR_FUNCTIONS(BlockVector); +VECTOR_FUNCTIONS(BlockVector); +#ifdef DEAL_II_USE_PETSC +VECTOR_FUNCTIONS(PETScWrappers::Vector); +#endif +template +void +ConstraintMatrix::condense(const SparseMatrix &uncondensed, + SparseMatrix &condensed) const; +template +void +ConstraintMatrix::condense(SparseMatrix &uncondensed) const; -#define VectorType Vector -vector_functions -#undef VectorType - -#define VectorType Vector -vector_functions -#undef VectorType - -#define VectorType BlockVector -vector_functions -#undef VectorType - -#define VectorType BlockVector -vector_functions -#undef VectorType - +template +void +ConstraintMatrix::condense(const SparseMatrix &uncondensed, + SparseMatrix &condensed) const; +template +void +ConstraintMatrix::condense(SparseMatrix &uncondensed) const; -template void ConstraintMatrix::condense(const SparseMatrix &uncondensed, - SparseMatrix &condensed) const; -template void ConstraintMatrix::condense(SparseMatrix &uncondensed) const; -template void ConstraintMatrix::condense(const SparseMatrix &uncondensed, - SparseMatrix &condensed) const; -template void ConstraintMatrix::condense(SparseMatrix &uncondensed) const; +// block sparse matrices are only implemented for one of the two matrix +// functions (the single-argument, in-place function) +template +void +ConstraintMatrix::condense(BlockSparseMatrix &uncondensed) const; -// block sparse matrices are only implemented for one of the two matrix functions -template void ConstraintMatrix::condense(BlockSparseMatrix &uncondensed) const; +template +void +ConstraintMatrix::condense(BlockSparseMatrix &uncondensed) const; diff --git a/deal.II/deal.II/source/fe/fe.cc b/deal.II/deal.II/source/fe/fe.cc index dd9c5f779b..bb210972e0 100644 --- a/deal.II/deal.II/source/fe/fe.cc +++ b/deal.II/deal.II/source/fe/fe.cc @@ -236,7 +236,7 @@ FiniteElementBase::shape_grad_grad_component (const unsigned int, template const FullMatrix & -FiniteElementBase::restrict (const unsigned int child) const +FiniteElementBase::get_restriction_matrix (const unsigned int child) const { Assert (child::children_per_cell, ExcIndexRange(child, 0, GeometryInfo::children_per_cell)); @@ -248,7 +248,7 @@ FiniteElementBase::restrict (const unsigned int child) const template const FullMatrix & -FiniteElementBase::prolongate (const unsigned int child) const +FiniteElementBase::get_prolongation_matrix (const unsigned int child) const { Assert (child::children_per_cell, ExcIndexRange(child, 0, GeometryInfo::children_per_cell)); diff --git a/deal.II/deal.II/source/fe/fe_system.cc b/deal.II/deal.II/source/fe/fe_system.cc index 9ae5a5cbb0..00726f3858 100644 --- a/deal.II/deal.II/source/fe/fe_system.cc +++ b/deal.II/deal.II/source/fe/fe_system.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -1700,11 +1700,13 @@ void FESystem::initialize () { if (do_restriction) this->restriction[child] (i,j) - = base_element(base).restrict(child)(base_index_i,base_index_j); + = (base_element(base) + .get_restriction_matrix(child)(base_index_i,base_index_j)); if (do_prolongation) this->prolongation[child] (i,j) - = base_element(base).prolongate(child)(base_index_i,base_index_j); + = (base_element(base) + .get_prolongation_matrix(child)(base_index_i,base_index_j)); }; }; diff --git a/deal.II/deal.II/source/fe/fe_values.cc b/deal.II/deal.II/source/fe/fe_values.cc index 7ac4f7d1c0..913b37d8a0 100644 --- a/deal.II/deal.II/source/fe/fe_values.cc +++ b/deal.II/deal.II/source/fe/fe_values.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -241,7 +242,7 @@ template template void FEValuesBase:: -get_function_grads (const InputVector &fe_function, +get_function_grads (const InputVector &fe_function, std::vector > &gradients) const { Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField()); @@ -341,7 +342,7 @@ template template void FEValuesBase:: -get_function_2nd_derivatives (const InputVector &fe_function, +get_function_2nd_derivatives (const InputVector &fe_function, std::vector > &second_derivatives) const { Assert (fe->n_components() == 1, @@ -901,6 +902,17 @@ void FEValuesBase::get_function_values > (const BlockVector&, std::vector&) const; +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_values +(const PETScWrappers::Vector &, + std::vector&) const; +template +void FEValuesBase::get_function_values +(const PETScWrappers::Vector &, + std::vector&) const; +#endif + //----------------------------------------------------------------------------- template @@ -924,6 +936,13 @@ void FEValuesBase::get_function_values > (const BlockVector &, std::vector > &) const; +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_values +(const PETScWrappers::Vector &, + std::vector > &) const; +#endif + //----------------------------------------------------------------------------- template @@ -938,6 +957,17 @@ template void FEValuesBase::get_function_grads > (const BlockVector &, std::vector > &) const; +template +void FEValuesBase::get_function_grads > +(const BlockVector &, + std::vector > &) const; + +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_grads +(const PETScWrappers::Vector &, + std::vector > &) const; +#endif //----------------------------------------------------------------------------- @@ -958,6 +988,13 @@ void FEValuesBase::get_function_grads > (const BlockVector &, std::vector > > &) const; +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_grads +(const PETScWrappers::Vector &, + std::vector > > &) const; +#endif + //----------------------------------------------------------------------------- template @@ -972,6 +1009,14 @@ template void FEValuesBase::get_function_2nd_derivatives > (const BlockVector &, std::vector > &) const; + +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_2nd_derivatives +(const PETScWrappers::Vector &, + std::vector > &) const; +#endif + //----------------------------------------------------------------------------- template @@ -986,3 +1031,10 @@ template void FEValuesBase::get_function_2nd_derivatives > (const BlockVector &, std::vector > > &) const; + +#ifdef DEAL_II_USE_PETSC +template +void FEValuesBase::get_function_2nd_derivatives +(const PETScWrappers::Vector &, + std::vector > > &) const; +#endif diff --git a/deal.II/deal.II/source/grid/grid_generator.cc b/deal.II/deal.II/source/grid/grid_generator.cc index c8c9b65334..55e392be21 100644 --- a/deal.II/deal.II/source/grid/grid_generator.cc +++ b/deal.II/deal.II/source/grid/grid_generator.cc @@ -1242,7 +1242,9 @@ void GridGenerator::laplace_transformation (Triangulation &tria, // solve the dim problems with // different right hand sides. - std::vector > us(dim, Vector (dof_handler.n_dofs())); + Vector us[dim]; + for (unsigned int i=0; i threads; diff --git a/deal.II/deal.II/source/grid/grid_refinement.cc b/deal.II/deal.II/source/grid/grid_refinement.cc index 72bf2f6b71..084a3434e8 100644 --- a/deal.II/deal.II/source/grid/grid_refinement.cc +++ b/deal.II/deal.II/source/grid/grid_refinement.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -11,6 +11,9 @@ // //---------------------------- grid_refinement.cc --------------------------- +#include +#include + #include #include #include @@ -24,14 +27,64 @@ -template -void GridRefinement::qsort_index(const Vector &a, - std::vector &ind, - int l, - int r) +namespace +{ + template + inline + number + max_element (const Vector &criteria) + { + return *std::max_element(criteria.begin(), criteria.end()); + } + + + + template + inline + number + min_element (const Vector &criteria) + { + return *std::min_element(criteria.begin(), criteria.end()); + } + + + + PetscScalar + max_element (const PETScWrappers::VectorBase &criteria) + { + // this is horribly slow (since we have + // to get the array of values from PETSc + // in every iteration), but works + PetscScalar m = 0; + for (unsigned int i=0; i +void GridRefinement::qsort_index (const Vector &a, + std::vector &ind, + int l, + int r) { - int i,j,t; - number v; + int i,j; + typename Vector::value_type v; if (r<=l) return; @@ -45,25 +98,17 @@ void GridRefinement::qsort_index(const Vector &a, { ++i; } - while ((a(ind[i])>v)&&(iv) && (i0)); + while ((a(ind[j])0)); if (i &a, -template -void GridRefinement::refine (Triangulation &tria, - const Vector &criteria, - const double threshold) +template +void GridRefinement::refine (Triangulation &tria, + const Vector &criteria, + const double threshold) { Assert (criteria.size() == tria.n_active_cells(), ExcInvalidVectorSize(criteria.size(), tria.n_active_cells())); - Assert (*std::min_element(criteria.begin(), criteria.end()) >= 0, - ExcInvalidParameterValue()); + Assert (criteria.is_non_negative (), ExcInvalidParameterValue()); // when all indicators are zero we // do not need to refine but only @@ -110,15 +154,14 @@ void GridRefinement::refine (Triangulation &tria, -template -void GridRefinement::coarsen (Triangulation &tria, - const Vector &criteria, - const double threshold) +template +void GridRefinement::coarsen (Triangulation &tria, + const Vector &criteria, + const double threshold) { Assert (criteria.size() == tria.n_active_cells(), ExcInvalidVectorSize(criteria.size(), tria.n_active_cells())); - Assert (*std::min_element(criteria.begin(), criteria.end()) >= 0, - ExcInvalidParameterValue()); + Assert (criteria.is_non_negative (), ExcInvalidParameterValue()); typename Triangulation::active_cell_iterator cell = tria.begin_active(); const unsigned int n_cells = criteria.size(); @@ -131,27 +174,26 @@ void GridRefinement::coarsen (Triangulation &tria, -template +template void -GridRefinement::refine_and_coarsen_fixed_number (Triangulation &tria, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction) +GridRefinement::refine_and_coarsen_fixed_number (Triangulation &tria, + const Vector &criteria, + const double top_fraction, + const double bottom_fraction) { // correct number of cells is // checked in @p{refine} Assert ((top_fraction>=0) && (top_fraction<=1), ExcInvalidParameterValue()); Assert ((bottom_fraction>=0) && (bottom_fraction<=1), ExcInvalidParameterValue()); Assert (top_fraction+bottom_fraction <= 1, ExcInvalidParameterValue()); - Assert (*std::min_element(criteria.begin(), criteria.end()) >= 0, - ExcInvalidParameterValue()); + Assert (criteria.is_non_negative (), ExcInvalidParameterValue()); const int refine_cells=static_cast(top_fraction*criteria.size()); const int coarsen_cells=static_cast(bottom_fraction*criteria.size()); if (refine_cells || coarsen_cells) { - Vector tmp(criteria); + ::Vector tmp(criteria); if (refine_cells) { std::nth_element (tmp.begin(), tmp.begin()+refine_cells, @@ -172,26 +214,25 @@ GridRefinement::refine_and_coarsen_fixed_number (Triangulation &tria, -template +template void -GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation &tria, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction) +GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation &tria, + const Vector &criteria, + const double top_fraction, + const double bottom_fraction) { // correct number of cells is // checked in @p{refine} Assert ((top_fraction>=0) && (top_fraction<=1), ExcInvalidParameterValue()); Assert ((bottom_fraction>=0) && (bottom_fraction<=1), ExcInvalidParameterValue()); Assert (top_fraction+bottom_fraction <= 1, ExcInvalidParameterValue()); - Assert (*std::min_element(criteria.begin(), criteria.end()) >= 0, - ExcInvalidParameterValue()); + Assert (criteria.is_non_negative (), ExcInvalidParameterValue()); // let tmp be the cellwise square of the // error, which is what we have to sum // up and compare with // @p{fraction_of_error*total_error}. - Vector tmp(criteria); + ::Vector tmp(criteria); const double total_error = tmp.l1_norm(); // sort the largest criteria to the @@ -199,13 +240,13 @@ GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation &tria, std::sort (tmp.begin(), tmp.end(), std::greater()); // compute thresholds - typename Vector::const_iterator pp=tmp.begin(); + typename ::Vector::const_iterator pp=tmp.begin(); for (double sum=0; (sum::const_iterator qq=(tmp.end()-1); + typename ::Vector::const_iterator qq=(tmp.end()-1); for (double sum=0; (sum &tria, // threshold if it equals the // largest indicator and the // top_fraction!=1 - if ((top_threshold == *std::max_element(criteria.begin(), criteria.end())) && + if ((top_threshold == max_element(criteria)) && (top_fraction != 1)) top_threshold *= 0.999; @@ -251,24 +292,23 @@ GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation &tria, bottom_threshold = 0.999*top_threshold; // actually flag cells - if (top_threshold < *std::max_element(criteria.begin(), criteria.end())) + if (top_threshold < max_element(criteria)) refine (tria, criteria, top_threshold); - if (bottom_threshold > *std::min_element(criteria.begin(), criteria.end())) + if (bottom_threshold > min_element(criteria)) coarsen (tria, criteria, bottom_threshold); } -template +template void -GridRefinement::refine_and_coarsen_optimize (Triangulation &tria, - const Vector &criteria) +GridRefinement::refine_and_coarsen_optimize (Triangulation &tria, + const Vector &criteria) { Assert (criteria.size() == tria.n_active_cells(), ExcInvalidVectorSize(criteria.size(), tria.n_active_cells())); - Assert (*std::min_element(criteria.begin(), criteria.end()) >= 0, - ExcInvalidParameterValue()); + Assert (criteria.is_non_negative (), ExcInvalidParameterValue()); // get an increasing order on // the error indicator @@ -312,56 +352,116 @@ GridRefinement::refine_and_coarsen_optimize (Triangulation &tria, refine(tria,criteria,criteria(tmp[minArg])); } + // explicit instantiations -template void GridRefinement -::refine (Triangulation &, - const Vector &, - const double); - -template void GridRefinement -::refine (Triangulation &, - const Vector &, - const double); - -template void GridRefinement -::coarsen (Triangulation &, - const Vector &, - const double); - -template void GridRefinement -::coarsen (Triangulation &, - const Vector &, - const double); - - -template void GridRefinement -::refine_and_coarsen_fixed_number (Triangulation &, - const Vector &, - const double top_fraction, - const double bottom_fraction); - -template void GridRefinement -::refine_and_coarsen_fixed_number (Triangulation &, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction); - -template void GridRefinement -::refine_and_coarsen_fixed_fraction (Triangulation &, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction); - -template void GridRefinement -::refine_and_coarsen_fixed_fraction (Triangulation &, - const Vector &criteria, - const double top_fraction, - const double bottom_fraction); - -template void GridRefinement -::refine_and_coarsen_optimize (Triangulation &, - const Vector &criteria); - -template void GridRefinement -::refine_and_coarsen_optimize (Triangulation &, - const Vector &criteria); +template +void +GridRefinement:: +refine (Triangulation &, + const Vector &, + const double); + +template +void +GridRefinement:: +refine (Triangulation &, + const Vector &, + const double); + +template +void +GridRefinement:: +coarsen (Triangulation &, + const Vector &, + const double); + +template +void +GridRefinement:: +coarsen (Triangulation &, + const Vector &, + const double); + + +template +void +GridRefinement:: +refine_and_coarsen_fixed_number (Triangulation &, + const Vector &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_fixed_number (Triangulation &, + const Vector &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_fixed_fraction (Triangulation &, + const Vector &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_fixed_fraction (Triangulation &, + const Vector &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_optimize (Triangulation &, + const Vector &); + +template +void +GridRefinement:: +refine_and_coarsen_optimize (Triangulation &, + const Vector &); + +#ifdef DEAL_II_USE_PETSC +template +void +GridRefinement:: +refine (Triangulation &, + const PETScWrappers::VectorBase &, + const double); + +template +void +GridRefinement:: +coarsen (Triangulation &, + const PETScWrappers::VectorBase &, + const double); + + +template +void +GridRefinement:: +refine_and_coarsen_fixed_number (Triangulation &, + const PETScWrappers::VectorBase &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_fixed_fraction (Triangulation &, + const PETScWrappers::VectorBase &, + const double, + const double); + +template +void +GridRefinement:: +refine_and_coarsen_optimize (Triangulation &, + const PETScWrappers::VectorBase &); +#endif diff --git a/deal.II/deal.II/source/multigrid/mg_transfer_block.cc b/deal.II/deal.II/source/multigrid/mg_transfer_block.cc index 73e6fe919b..99ef32d7d4 100644 --- a/deal.II/deal.II/source/multigrid/mg_transfer_block.cc +++ b/deal.II/deal.II/source/multigrid/mg_transfer_block.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -227,7 +227,7 @@ void MGTransferBlockBase::build_matrices ( // prolongation matrix for // this child const FullMatrix &prolongation - = mg_dof.get_fe().prolongate(child); + = mg_dof.get_fe().get_prolongation_matrix (child); cell->child(child)->get_mg_dof_indices (dof_indices_child); @@ -266,7 +266,7 @@ void MGTransferBlockBase::build_matrices ( // prolongation matrix for // this child const FullMatrix &prolongation - = mg_dof.get_fe().prolongate(child); + = mg_dof.get_fe().get_prolongation_matrix (child); cell->child(child)->get_mg_dof_indices (dof_indices_child); diff --git a/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc b/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc index 2ece6ce2d0..27594988aa 100644 --- a/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc +++ b/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -112,7 +112,7 @@ void MGTransferPrebuilt::build_matrices ( // prolongation matrix for // this child const FullMatrix &prolongation - = mg_dof.get_fe().prolongate(child); + = mg_dof.get_fe().get_prolongation_matrix (child); Assert (prolongation.n() != 0, ExcNoProlongation()); @@ -149,7 +149,7 @@ void MGTransferPrebuilt::build_matrices ( // prolongation matrix for // this child const FullMatrix &prolongation - = mg_dof.get_fe().prolongate(child); + = mg_dof.get_fe().get_prolongation_matrix (child); cell->child(child)->get_mg_dof_indices (dof_indices_child); diff --git a/deal.II/deal.II/source/numerics/data_out.cc b/deal.II/deal.II/source/numerics/data_out.cc index 26f2529438..23aed66ee3 100644 --- a/deal.II/deal.II/source/numerics/data_out.cc +++ b/deal.II/deal.II/source/numerics/data_out.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -35,40 +36,95 @@ template -DataOut_DoFData::DataEntry:: -DataEntry (const Vector *data, - const std::vector &names) +DataOut_DoFData::DataEntryBase:: +DataEntryBase (const std::vector &names) : - single_data(data), - has_block(false), names(names) {} template -DataOut_DoFData::DataEntry:: -DataEntry (const BlockVector *data, +DataOut_DoFData:: +DataEntryBase::~DataEntryBase () +{} + + + +template +template +DataOut_DoFData:: +DataEntry:: +DataEntry (const VectorType *data, const std::vector &names) : - block_data(data), - has_block(true), - names(names) + DataEntryBase (names), + vector (data) {} template +template +double +DataOut_DoFData:: +DataEntry:: +get_cell_data_value (const unsigned int cell_number) const +{ + return (*vector)(cell_number); +} + + + +template +template +void +DataOut_DoFData:: +DataEntry:: +get_function_values (const FEValuesBase &fe_patch_values, + std::vector > &patch_values_system) const +{ + fe_patch_values.get_function_values (*vector, patch_values_system); +} + + + +template +template +void +DataOut_DoFData:: +DataEntry:: +get_function_values (const FEValuesBase &fe_patch_values, + std::vector &patch_values) const +{ + fe_patch_values.get_function_values (*vector, patch_values); +} + + + +template +template unsigned int DataOut_DoFData:: -DataEntry::memory_consumption () const +DataEntry::memory_consumption () const { - return (sizeof (single_data) + sizeof (block_data) + + return (sizeof (vector) + MemoryConsumption::memory_consumption (names)); } +template +template +void +DataOut_DoFData:: +DataEntry::clear () +{ + vector = 0; +} + + + template @@ -169,11 +225,11 @@ add_data_vector (const VECTOR &vec, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789_<>()"))); - DataEntry new_entry (&vec, names); + DataEntryBase * new_entry = new DataEntry(&vec, names); if (actual_type == type_dof_data) - dof_data.push_back (new_entry); + dof_data.push_back (boost::shared_ptr(new_entry)); else - cell_data.push_back (new_entry); + cell_data.push_back (boost::shared_ptr(new_entry)); } @@ -240,16 +296,10 @@ DataOut_DoFData:: clear_input_data_references () { for (unsigned int i=0; iclear (); for (unsigned int i=0; iclear (); if (dofs != 0) { @@ -282,20 +332,24 @@ DataOut_DoFData::clear () template std::vector -DataOut_DoFData::get_dataset_names () const +DataOut_DoFData:: +get_dataset_names () const { std::vector names; // collect the names of dof // and cell data - for (typename std::vector::const_iterator d=dof_data.begin(); + typedef + typename std::vector >::const_iterator + data_iterator; + + for (data_iterator d=dof_data.begin(); d!=dof_data.end(); ++d) - for (unsigned int i=0; inames.size(); ++i) - names.push_back (d->names[i]); - for (typename std::vector::const_iterator d=cell_data.begin(); - d!=cell_data.end(); ++d) + for (unsigned int i=0; i<(*d)->names.size(); ++i) + names.push_back ((*d)->names[i]); + for (data_iterator d=cell_data.begin(); d!=cell_data.end(); ++d) { - Assert (d->names.size() == 1, ExcInternalError()); - names.push_back (d->names[0]); + Assert ((*d)->names.size() == 1, ExcInternalError()); + names.push_back ((*d)->names[0]); }; return names; @@ -318,8 +372,6 @@ DataOut_DoFData::memory_consumption ( { return (DataOutInterface::memory_consumption () + MemoryConsumption::memory_consumption (dofs) + - MemoryConsumption::memory_consumption (dof_data) + - MemoryConsumption::memory_consumption (cell_data) + MemoryConsumption::memory_consumption (patches)); } @@ -376,12 +428,8 @@ void DataOut::build_some_patches (Data data) { if (data.n_components == 1) { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values); for (unsigned int q=0; qdata(dataset,q) = data.patch_values[q]; @@ -389,12 +437,8 @@ void DataOut::build_some_patches (Data data) else // system of components { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values_system); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values_system); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values_system); for (unsigned int component=0; component::build_some_patches (Data data) // then do the cell data for (unsigned int dataset=0; datasetcell_data.size(); ++dataset) { - if (this->cell_data[dataset].has_block) - { - const double value = (*this->cell_data[dataset].block_data)(cell_number); - for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = - value; - } else { - const double value = (*this->cell_data[dataset].single_data)(cell_number); - for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = - value; - } - }; - }; + const double value + = this->cell_data[dataset]->get_cell_data_value (cell_number); + for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = + value; + } + } // now fill the neighbors fields for (unsigned int f=0; f::faces_per_cell; ++f) @@ -662,24 +699,37 @@ DataOut::next_cell (const typename DoFHandler::cell_iterator &cell) // explicit instantiations template class DataOut_DoFData; + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::vector &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( const BlockVector &vec, const std::vector &name, const DataVectorType type); + +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::vector &name, + const DataVectorType type); +#endif + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::string &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( @@ -687,26 +737,49 @@ add_data_vector > ( const std::string &name, const DataVectorType type); +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::string &name, + const DataVectorType type); +#endif + + template class DataOut_DoFData; + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::vector &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( const BlockVector &vec, const std::vector &name, const DataVectorType type); + +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::vector &name, + const DataVectorType type); +#endif + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::string &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( @@ -714,6 +787,16 @@ add_data_vector > ( const std::string &name, const DataVectorType type); +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::string &name, + const DataVectorType type); +#endif + + template class DataOut; @@ -721,24 +804,37 @@ template class DataOut; // for 3d, also generate an extra class #if deal_II_dimension >= 2 template class DataOut_DoFData; + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::vector &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( const BlockVector &vec, const std::vector &name, const DataVectorType type); + +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::vector &name, + const DataVectorType type); +#endif + template void DataOut_DoFData:: add_data_vector > ( const Vector &vec, const std::string &name, const DataVectorType type); + template void DataOut_DoFData:: add_data_vector > ( @@ -746,5 +842,13 @@ add_data_vector > ( const std::string &name, const DataVectorType type); +#ifdef DEAL_II_USE_PETSC +template void +DataOut_DoFData:: +add_data_vector ( + const PETScWrappers::Vector &vec, + const std::string &name, + const DataVectorType type); +#endif #endif diff --git a/deal.II/deal.II/source/numerics/data_out_faces.cc b/deal.II/deal.II/source/numerics/data_out_faces.cc index a5225216b8..892e54b4ac 100644 --- a/deal.II/deal.II/source/numerics/data_out_faces.cc +++ b/deal.II/deal.II/source/numerics/data_out_faces.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -72,12 +72,8 @@ void DataOutFaces::build_some_patches (Data data) { if (data.n_components == 1) { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values); for (unsigned int q=0; qdata(dataset,q) = data.patch_values[q]; @@ -85,12 +81,8 @@ void DataOutFaces::build_some_patches (Data data) else // system of components { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values_system); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values_system); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values_system); for (unsigned int component=0; component::build_some_patches (Data data) const unsigned int cell_number = std::distance (this->dofs->begin_active(), typename DoFHandler::active_cell_iterator(face.first)); - - if (this->cell_data[dataset].has_block) - { - const double value = (*this->cell_data[dataset].block_data)(cell_number); - for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = - value; - } else { - const double value = (*this->cell_data[dataset].single_data)(cell_number); - for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = - value; - } + + const double value + = this->cell_data[dataset]->get_cell_data_value (cell_number); + for (unsigned int q=0; qdata(dataset+this->dof_data.size()*data.n_components,q) = + value; }; }; // next cell (patch) in this thread diff --git a/deal.II/deal.II/source/numerics/data_out_rotation.cc b/deal.II/deal.II/source/numerics/data_out_rotation.cc index 9a1ffa73e6..34d0cad067 100644 --- a/deal.II/deal.II/source/numerics/data_out_rotation.cc +++ b/deal.II/deal.II/source/numerics/data_out_rotation.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -159,12 +159,8 @@ void DataOutRotation::build_some_patches (Data data) { if (data.n_components == 1) { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values); switch (dim) { @@ -194,12 +190,8 @@ void DataOutRotation::build_some_patches (Data data) else // system of components { - if (this->dof_data[dataset].has_block) - fe_patch_values.get_function_values (*this->dof_data[dataset].block_data, - data.patch_values_system); - else - fe_patch_values.get_function_values (*this->dof_data[dataset].single_data, - data.patch_values_system); + this->dof_data[dataset]->get_function_values (fe_patch_values, + data.patch_values_system); for (unsigned int component=0; component::build_some_patches (Data data) // then do the cell data for (unsigned int dataset=0; datasetcell_data.size(); ++dataset) { - const double value = this->cell_data[dataset].has_block ? - (*this->cell_data[dataset].block_data)(cell_number) : - (*this->cell_data[dataset].single_data)(cell_number); + const double value + = this->cell_data[dataset]->get_cell_data_value (cell_number); switch (dim) { case 1: diff --git a/deal.II/deal.II/source/numerics/data_out_stack.cc b/deal.II/deal.II/source/numerics/data_out_stack.cc index e6a1bbf628..282c38eec2 100644 --- a/deal.II/deal.II/source/numerics/data_out_stack.cc +++ b/deal.II/deal.II/source/numerics/data_out_stack.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -387,9 +387,19 @@ std::vector DataOutStack::get_dataset_names () const // explicit instantiations template class DataOutStack; + template void DataOutStack:: add_data_vector (const Vector &vec, const std::string &name); + +template void DataOutStack:: +add_data_vector (const Vector &vec, + const std::vector &names); + template void DataOutStack:: add_data_vector (const Vector &vec, const std::string &name); + +template void DataOutStack:: +add_data_vector (const Vector &vec, + const std::vector &names); diff --git a/deal.II/deal.II/source/numerics/derivative_approximation.cc b/deal.II/deal.II/source/numerics/derivative_approximation.cc index 09dcd4deb6..b7e9509d58 100644 --- a/deal.II/deal.II/source/numerics/derivative_approximation.cc +++ b/deal.II/deal.II/source/numerics/derivative_approximation.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -709,86 +710,59 @@ DerivativeApproximation::approximate (const Mapping &mapping, // explicit instantiations -template -void -DerivativeApproximation:: -approximate_gradient -(const Mapping &mapping, - const DoFHandler &dof_handler, - const Vector &solution, - Vector &derivative_norm, - const unsigned int component); -template -void -DerivativeApproximation:: -approximate_gradient -(const Mapping &mapping, - const DoFHandler &dof_handler, - const BlockVector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_gradient -(const DoFHandler &dof_handler, - const Vector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_gradient -(const DoFHandler &dof_handler, - const BlockVector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_second_derivative -(const Mapping &mapping, - const DoFHandler &dof_handler, - const Vector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_second_derivative -(const Mapping &mapping, - const DoFHandler &dof_handler, - const BlockVector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_second_derivative -(const DoFHandler &dof_handler, - const Vector &solution, - Vector &derivative_norm, - const unsigned int component); - -template -void -DerivativeApproximation:: -approximate_second_derivative -(const DoFHandler &dof_handler, - const BlockVector &solution, - Vector &derivative_norm, - const unsigned int component); +#define INSTANTIATE(InputVector) \ +template \ +void \ +DerivativeApproximation:: \ +approximate_gradient \ +(const Mapping &mapping, \ + const DoFHandler &dof_handler, \ + const InputVector &solution, \ + Vector &derivative_norm, \ + const unsigned int component); \ + \ +template \ +void \ +DerivativeApproximation:: \ +approximate_gradient \ +(const DoFHandler &dof_handler, \ + const InputVector &solution, \ + Vector &derivative_norm, \ + const unsigned int component); \ + \ +template \ +void \ +DerivativeApproximation:: \ +approximate_second_derivative \ +(const Mapping &mapping, \ + const DoFHandler &dof_handler, \ + const InputVector &solution, \ + Vector &derivative_norm, \ + const unsigned int component); \ + \ +template \ +void \ +DerivativeApproximation:: \ +approximate_second_derivative \ +(const DoFHandler &dof_handler, \ + const InputVector &solution, \ + Vector &derivative_norm, \ + const unsigned int component) + +INSTANTIATE(Vector); +INSTANTIATE(Vector); +INSTANTIATE(BlockVector); +INSTANTIATE(BlockVector); + +#ifdef DEAL_II_USE_PETSC +INSTANTIATE(PETScWrappers::Vector); +#endif // static variables // // on AIX, the linker is unhappy about some missing symbols. they -// should really be there, but explicitly instantiation them will also +// should really be there, but explicitly instantiating them will also // not hurt template const UpdateFlags diff --git a/deal.II/deal.II/source/numerics/error_estimator.cc b/deal.II/deal.II/source/numerics/error_estimator.cc index aee011d7c9..bdf6f80c96 100644 --- a/deal.II/deal.II/source/numerics/error_estimator.cc +++ b/deal.II/deal.II/source/numerics/error_estimator.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -84,18 +86,19 @@ PerThreadData (const unsigned int n_solution_vectors, // the following function is still independent of dimension, but it // calls dimension dependent functions template +template void KellyErrorEstimator::estimate (const Mapping &mapping, const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const Vector &solution, + const InputVector &solution, Vector &error, const std::vector &component_mask, const Function *coefficients, const unsigned int n_threads) { // just pass on to the other function - const std::vector*> solutions (1, &solution); + const std::vector solutions (1, &solution); std::vector*> errors (1, &error); estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors, component_mask, coefficients, n_threads); @@ -103,10 +106,11 @@ void KellyErrorEstimator::estimate (const Mapping &mapping, template +template void KellyErrorEstimator::estimate (const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const Vector &solution, + const InputVector &solution, Vector &error, const std::vector &component_mask, const Function *coefficients, @@ -123,12 +127,13 @@ void KellyErrorEstimator::estimate (const DoFHandler &dof_handler, #if deal_II_dimension == 1 template <> +template void KellyErrorEstimator<1>:: estimate_some (const Mapping<1> &, const DoFHandler<1> &, const Quadrature<0> &, const FunctionMap<1>::type &, - const std::vector*> &, + const std::vector &, const std::vector &, const Function<1> *, const std::pair , @@ -143,12 +148,13 @@ estimate_some (const Mapping<1> &, template <> +template void KellyErrorEstimator<1>:: estimate (const Mapping<1> &mapping, const DoFHandler<1> &dof_handler, const Quadrature<0> &, const FunctionMap<1>::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, std::vector*> &errors, const std::vector &component_mask_, const Function<1> *coefficient, @@ -253,7 +259,7 @@ estimate (const Mapping<1> &mapping, for (unsigned int n=0; n<2; ++n) { // find right active neighbor - DoFHandler::cell_iterator neighbor = cell->neighbor(n); + typename DoFHandler::cell_iterator neighbor = cell->neighbor(n); if (neighbor.state() == IteratorState::valid) while (neighbor->has_children()) neighbor = neighbor->child(n==0 ? 1 : 0); @@ -359,12 +365,13 @@ estimate (const Mapping<1> &mapping, template +template void KellyErrorEstimator:: estimate_some (const Mapping &mapping, const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, const std::pair this_thread, @@ -546,12 +553,13 @@ estimate_some (const Mapping &mapping, template +template void KellyErrorEstimator::estimate (const Mapping &mapping, const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, std::vector*> &errors, const std::vector &component_mask_, const Function *coefficients, @@ -644,7 +652,7 @@ KellyErrorEstimator::estimate (const Mapping &mapping // the whole thing Threads::ThreadGroup<> threads; for (unsigned int i=0; i::estimate_some) + threads += Threads::spawn (&KellyErrorEstimator::template estimate_some) (mapping, dof_handler, quadrature, neumann_bc, solutions, component_mask, coefficients, @@ -703,10 +711,11 @@ KellyErrorEstimator::estimate (const Mapping &mapping #endif template +template void KellyErrorEstimator::estimate (const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, std::vector*> &errors, const std::vector &component_mask, const Function *coefficients, @@ -723,11 +732,12 @@ void KellyErrorEstimator::estimate (const DoFHandler &do #if deal_II_dimension == 1 template <> +template void KellyErrorEstimator<1>:: integrate_over_regular_face (const DoFHandler<1> &, const Quadrature<0> &, const FunctionMap<1>::type &, - const std::vector*> &, + const std::vector &, const std::vector &, const Function<1> *, FaceIntegrals &, @@ -742,10 +752,11 @@ integrate_over_regular_face (const DoFHandler<1> &, template <> +template void KellyErrorEstimator<1>:: integrate_over_irregular_face (const DoFHandler<1> &, const Quadrature<0> &, - const std::vector*> &, + const std::vector &, const std::vector &, const Function<1> *, FaceIntegrals &, @@ -762,11 +773,12 @@ integrate_over_irregular_face (const DoFHandler<1> &, template +template void KellyErrorEstimator:: integrate_over_regular_face (const DoFHandler &dof_handler, const Quadrature &quadrature, const typename FunctionMap::type &neumann_bc, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, FaceIntegrals &face_integrals, @@ -954,10 +966,11 @@ integrate_over_regular_face (const DoFHandler &dof_handler, template +template void KellyErrorEstimator:: integrate_over_irregular_face (const DoFHandler &dof_handler, const Quadrature &quadrature, - const std::vector*> &solutions, + const std::vector &solutions, const std::vector &component_mask, const Function *coefficients, FaceIntegrals &face_integrals, @@ -1140,5 +1153,65 @@ integrate_over_irregular_face (const DoFHandler &dof_handler, // explicit instantiations - template class KellyErrorEstimator; + +// instantiate the externally visible functions +#define INSTANTIATE(InputVector) \ +template \ +void \ +KellyErrorEstimator:: \ +estimate (const Mapping &, \ + const DoFHandler &, \ + const Quadrature &, \ + const FunctionMap::type &, \ + const InputVector &, \ + Vector &, \ + const std::vector &, \ + const Function *, \ + const unsigned int ); \ + \ +template \ +void \ +KellyErrorEstimator:: \ +estimate (const DoFHandler &, \ + const Quadrature &, \ + const FunctionMap::type &, \ + const InputVector &, \ + Vector &, \ + const std::vector &, \ + const Function *, \ + const unsigned int ); \ + \ +template \ +void \ +KellyErrorEstimator:: \ +estimate (const Mapping &, \ + const DoFHandler &, \ + const Quadrature &, \ + const FunctionMap::type &, \ + const std::vector &, \ + std::vector*> &, \ + const std::vector &, \ + const Function *, \ + const unsigned int ); \ + \ +template \ +void \ +KellyErrorEstimator:: \ +estimate (const DoFHandler &, \ + const Quadrature &, \ + const FunctionMap::type &, \ + const std::vector &, \ + std::vector*> &, \ + const std::vector &, \ + const Function *, \ + const unsigned int ) + +INSTANTIATE(Vector); +INSTANTIATE(Vector); +INSTANTIATE(BlockVector); +INSTANTIATE(BlockVector); + +#ifdef DEAL_II_USE_PETSC +INSTANTIATE(PETScWrappers::Vector); +#endif diff --git a/deal.II/doc/development/Makefile b/deal.II/doc/development/Makefile index 5fce2cfdb9..ff279d1f6a 100644 --- a/deal.II/doc/development/Makefile +++ b/deal.II/doc/development/Makefile @@ -24,6 +24,9 @@ makefiles.html: Makefile makefiles.1.html $D/common/Make.global_options makefile @echo '
  • DEAL_II_MINOR=$(DEAL_II_MINOR)' >> $@ @echo '
  • TARGET=$(TARGET)' >> $@ @echo '
  • USE_CONTRIB_HSL=$(USE_CONTRIB_HSL)' >> $@ + @echo '
  • USE_CONTRIB_PETSC=$(USE_CONTRIB_PETSC)' >> $@ + @echo '
  • DEAL_II_PETSC_DIR=$(DEAL_II_PETSC_DIR)' >> $@ + @echo '
  • DEAL_II_PETSC_ARCH=$(DEAL_II_PETSC_ARCH)' >> $@ @echo '
  • lib-path-base=$(lib-path-base)' >> $@ @echo '
  • lib-path-lac=$(lib-path-lac)' >> $@ @echo '
  • lib-path-deal2=$(lib-path-deal2)' >> $@ @@ -40,10 +43,15 @@ makefiles.html: Makefile makefiles.1.html $D/common/Make.global_options makefile @echo '
  • lib-deal2-3d.o=$(lib-deal2-3d.o)' >> $@ @echo '
  • lib-deal2-3d.g=$(lib-deal2-3d.g)' >> $@ @echo '
  • lib-contrib-hsl=$(lib-contrib-hsl)' >> $@ + @echo '
  • lib-contrib-petsc.g=$(lib-contrib-petsc.g)' >> $@ + @echo '
  • lib-contrib-petsc.o=$(lib-contrib-petsc.o)' >> $@ @echo '
  • include-path-base=$(include-path-base)' >> $@ @echo '
  • include-path-lac=$(include-path-lac)' >> $@ @echo '
  • include-path-deal2=$(include-path-deal2)' >> $@ @echo '
  • include-path-contrib-hsl=$(include-path-contrib-hsl)' >> $@ + @echo '
  • include-path-contrib-petsc=$(include-path-contrib-petsc)' >> $@ + @echo '
  • include-path-contrib-petsc-bmake=$(include-path-contrib-petsc-bmake)' >> $@ + @echo '
  • include-path-contrib-petsc-mpi=$(include-path-contrib-petsc-mpi)' >> $@ @echo '
  • INCLUDE=$(INCLUDE)' >> $@ @echo '
  • CXXFLAGS.g=$(CXXFLAGS.g)' >> $@ @echo '
  • CXXFLAGS.o=$(CXXFLAGS.o)' >> $@ diff --git a/deal.II/doc/development/makefiles.1.html b/deal.II/doc/development/makefiles.1.html index 76fadde210..1dcb6c2b71 100644 --- a/deal.II/doc/development/makefiles.1.html +++ b/deal.II/doc/development/makefiles.1.html @@ -177,6 +177,39 @@ file for more information on installation of HSL subroutines.)

    + + +
    USE_CONTRIB_PETSC
    +

    + yes indicates whether the interfaces to the PETSc + library shall be compiled. no otherwise. + (See the + ReadMe + file for more information on installation of PETSc.) +

    +
    + + +
    DEAL_II_PETSC_DIR
    +

    + If USE_CONTRIB_PETSC is yes, then this + variable has the path to the PETSc library, as either given by the + PETSC_DIR environment variable, or the + --with-petsc switch on the command line upon + configuration of the deal.II library. +

    +
    + + +
    DEAL_II_PETSC_ARCH
    +

    + If USE_CONTRIB_PETSC is yes, then this + variable stores the architecture for which PETSc was compiled, as + either given by the PETSC_ARCH environment variable, + or the --with-petsc-arch switch on the command line + upon configuration of the deal.II library. +

    +
    @@ -278,6 +311,16 @@ subroutines.)

    + +
    lib-contrib-petsc.g lib-contrib-petsc.o
    +

    + Paths and names of the component libraries of the PETSc package, if + found and used at configuration time. + (See the + ReadMe + file for more information on installation of PETSc.) +

    +
    @@ -319,6 +362,21 @@ +
    include-path-contrib-petsc + include-path-contrib-petsc-bmake + include-path-contrib-petsc-mpi +
    +

    + If PETSc is used, then these variables have the paths to the usual + PETSc include files, the PETSc architecture dependent include + files, and the PETSC MPI dependent include files. + (See the + ReadMe + file for more information on installation of PETSC.) +

    +
    + +
    include-path-deal2

    Same for the /deal.II library. Include files are in diff --git a/deal.II/doc/doxygen/Makefile b/deal.II/doc/doxygen/Makefile.in similarity index 54% rename from deal.II/doc/doxygen/Makefile rename to deal.II/doc/doxygen/Makefile.in index 24d6abca4e..35e491a208 100644 --- a/deal.II/doc/doxygen/Makefile +++ b/deal.II/doc/doxygen/Makefile.in @@ -10,11 +10,11 @@ private: $(MAKE) html %.tag: %.dox - doxygen $< + @DOXYGEN@ $< -base.tag: options.dox base.dox ../../base/include/*/*.h headers/base/*.h -lac.tag: options.dox lac.dox base.tag ../../lac/include/*/*.h headers/lac/*.h -deal.tag: options.dox deal.dox lac.tag ../../deal.II/include/*/*.h headers/deal.II/*.h +base.tag: ../../base/include/*/*.h headers/base/*.h +lac.tag: base.tag ../../lac/include/*/*.h headers/lac/*.h +deal.tag: lac.tag ../../deal.II/include/*/*.h headers/deal.II/*.h base: base.tag lac: lac.tag diff --git a/deal.II/doc/doxygen/options.dox.in b/deal.II/doc/doxygen/options.dox.in index 99de9060b2..280ff5a48e 100644 --- a/deal.II/doc/doxygen/options.dox.in +++ b/deal.II/doc/doxygen/options.dox.in @@ -6,10 +6,10 @@ PROJECT_NUMBER = @DEAL_II_VERSION@ OUTPUT_DIRECTORY = . OUTPUT_LANGUAGE = English -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES BRIEF_MEMBER_DESC = YES diff --git a/deal.II/doc/faq.html b/deal.II/doc/faq.html index 4fb383739f..db36547586 100644 --- a/deal.II/doc/faq.html +++ b/deal.II/doc/faq.html @@ -31,6 +31,8 @@ with gcc version 2.96!

  • Can I use deal.II on a Windows platform? +
  • Does deal.II support parallel + computing?
  • I can't build the online documentation under Cygwin!
  • Can I use/implement triangles/tetrahedra in deal.II? @@ -231,6 +233,44 @@ + +

    Does deal.II support parallel computing?

    + +

    + Yes. If you use the --with-multithreading + --enable-multithreading flags when you run ./configure + (see the README file), then the + library will be set up to use multiple threads for various tasks, and you + can also use multiple threads in your program. See the example programs + to see how to do the latter. On machines with more than one processor + (i.e. SMP machines), using this functionality makes a lot of sense and can + significantly accelerate a program. +

    + +

    + By default, deal.II does not support operations on + clusters of computers that communicate via MPI. However, it also doesn't + prohibit you from doing so in your application programs (and there are a + number of programs that actually do this), it just doesn't implement + anything that actively uses MPI functionality. +

    + +

    + On the other hand, newer versions of deal.II have + interfaces to the PETSc library + that implements a lot of functionality for distributed linear algebra, + i.e. for operations on vectors and matrices that are distributed across a + cluster of machines coupled via MPI. By using these wrapper classes for + linear algebra, it is possible to implement programs that work on truly + large problems by distributing computations. +

    + +

    + For questions how to set up deal.II to use PETSc, refer + to the readme file. +

    + +

    Can I use/implement triangles/tetrahedra in deal.II?

    @@ -265,7 +305,7 @@

    To give only a very brief overview of what is possible, here is a list of the nontrivial problems that were treated by the programs - that only the main authors wrote to date: + that the main authors alone wrote to date:

    • Time-dependent acoustic and elastic wave equation, including nonlocal absorbing boundary conditions; @@ -273,7 +313,11 @@ element method;
    • General hyperbolic problems including Euler flow, using the discontinuous Galerkin finite element method; -
    • Distributed parameter estimation problems. +
    • Distributed parameter estimation problems; +
    • Mixed finite element discretization of a mortar multiblock formulation + of the Laplace equation; +
    • Large-deformation elasto-plasticity in the simulation of plate + tectonics.

    diff --git a/deal.II/doc/future.html b/deal.II/doc/future.html index 9ef442f614..304986cebd 100644 --- a/deal.II/doc/future.html +++ b/deal.II/doc/future.html @@ -25,8 +25,7 @@ deal.II. While this is running on globally refined grids, we are still having problems on locally refined meshes. For those, multigrid is only applicable with - DG methods yet. We hope to have them sorted out for the next - major release. + DG methods yet.

  • @@ -63,12 +62,13 @@

  • - A better test-suite: We have a small - suite of programs (approximately 190 programs with roughly - 37,000 lines of code at present) that are run automatically + A better test-suite: We have a + suite of programs (approximately 400 programs with roughly + 54,000 lines of code at present) that are run automatically for regression tests each night. Some of these are modified real-life applications, so they should cover a relevant part of the - library, but it would be necessary to reach every corner of + library, and some others test certain parts of the library + extensively, but it would be necessary to reach every corner of the library to be sure a certain patch does not break something. Also, a complete test-suite for the library would be quite valuable for ports to new computer systems and diff --git a/deal.II/doc/news/c-petsc.html b/deal.II/doc/news/c-petsc.html new file mode 100644 index 0000000000..a4e2c21b15 --- /dev/null +++ b/deal.II/doc/news/c-petsc.html @@ -0,0 +1,170 @@ + + + + + The deal.II news page + + + + + + +

    Changes after Version 4.0

    + +

    +This is the list of changes made after the release of +deal.II version 4.0. It is subdivided into changes +made to the three sub-libraries base, +lac, and deal.II, as well as +changes to the general infrastructure, +documentation, etc. +

    + +

    +All entries are signed with the names of the author. Regular +contributor's names are abbreviated by WB (Wolfgang Bangerth), GK +(Guido Kanschat), RH (Ralf Hartmann). +

    + + + +

    Incompatibilities

    + +
      +
    1. Changed: The FiniteElement classes had a + function restrict that returns the + restriction matrix from children to the mother cell. Unfortunately, + restrict has become a keyword in recent standards of the C + language, and some C++ compilers have picked this up. The function has + therefore been renamed get_restriction_matrix, which also better + reflects what it is actually doing. To keep consistent, we have also + rename the corresponding function prolongate to get_prolongation_matrix. +
      + (WB 2004/01/29) +

      + +
    + + + +

    General

    + +
      +
    1. New: There are now switches --with-petsc and + --with-petsc-arch to configure path and architecture of an + existing PETSc installation. If these switches are not used, then + environment variables are searched for this information. +
      + (WB 2004/01/26) +

      +
    + + + + +

    base

    + +
      +
    + + + + +

    lac

    + +
      +
    1. New: The Vector and BlockVector classes now have member functions + is_non_negative that check whether a vector + has no negative entries. +
      + (WB 2004/02/29) +

      + +
    2. Fixed: The SolverMinRes class had a nasty bug where we were + inadvertantly copying vectors; this could also have led to a memory + corruption bug. This is now fixed. +
      + (WB 2004/02/26) +

      + +
    3. New: There is now a function FullMatrix::add_scaled. It replaces the old + function FullMatrix::add which did the same, + but had a name that was incompatible with respective functions in the + other matrix classes. +
      + (WB 2004/02/23) +

      + +
    4. New: The Vector class now has operators to compare for + equality and inequality. +
      + (WB 2004/02/09) +

      + +
    5. New: The SparseMatrix::operator() generated an assertion + failure if the requested entry in the matrix isn't there. This has been + changed so that it actually throws an exception instead, also in + optimized mode. +
      + (WB 2004/02/06) +

      + +
    6. New: There is now a function SparseMatrix::frobenius_norm that computes the + Frobenius norm of a sparse matrix. +
      + (WB 2004/02/06) +

      + +
    7. Changed: In matrix-vector operations of the Full/SparseMatrix classes, source and destination + cannot be the same. We now also check that this is indeed the case. +
      + (WB 2004/01/26) +

      +
    + + + + +

    deal.II

    + +
      +
    1. Changed: The classes DataOut* and KellyErrorEstimator have been generalized to take + more and different vector types as input parameters. In particular, + they now take normal and block vectors over doubles and floats, as well + as PETSc vectors if PETSc support is detected during configuration of + the library. +
      + (WB 2004/03/01) +

      + +
    2. Changed: The template parameter of the functions in the GridRefinement class have been changed. Where they + previously denoted the type over which the Vector class is to be templated, they now mean the + actual vector class. Thus, they can be any other template class as long + as there are suitable operations defined over them. In addition, + the documentation stated that they must be vectors of floats; this + hasn't been true any more for quite a while already, and is duly + removed from the documentation. +
      + (WB 2004/02/28) +

      +
    + +
    +Last update $Date$ + + + diff --git a/deal.II/doc/readme.html b/deal.II/doc/readme.html index c734daee51..d01bca5b54 100644 --- a/deal.II/doc/readme.html +++ b/deal.II/doc/readme.html @@ -38,7 +38,7 @@ developed and tested on Unix or Unix-like systems only. It can be used positively on
      -
    • Linux on x86, with gcc 2.95, gcc 3.0, gcc 3.1/3.2; and Intel ICC +
    • Linux on x86, with gcc 2.95, 3.0, 3.1/3.2, 3.3 or 3.4; and Intel ICC 6.0, 7.0, 7.1 and 8.0;
    • Sun Solaris 2.5, 2.6, 7, 8, and 9 on Sparc, with gcc 2.95, gcc 3.0, and gcc 3.1/3.2; @@ -140,7 +140,7 @@
    • Make: we use GNU make, version 3.78 or 3.79 which also + target="_top">GNU make, version 3.78 or later which also has rather good support for parallel builds, so you may want to consider this version if you have a multiprocessor system. GNU make 3.77 had a serious flaw in the @@ -150,7 +150,7 @@ versions are likely to work, but since they are hardly installed on systems today, we don't regularly test this. Other make programs (i.e. non-GNU) will usually fail - to work. + to work and are not supported.

    • @@ -167,16 +167,25 @@

    • In case you want to generate the documentation from the - header files, you only need Perl installed. The scripts - generating the documentation are provided. + header files, you need a copy of doxygen on your machine (we use + version 1.3.2, later versions will presumable work as well). If you + have these program, you can generate all the API documentation on + your local machine. If not, you can still work with the library and + use the documentation provided on our homepage for reference.

    • - Previous versions of the library supported generation of - printable documentation. However, due to the size (around - 4000 pages) which refrains most people from printing, and - the high cost of supporting this option, we dropped the - possibility of printable documentation. + Doxygen also generates printable API documentation. It is located + in the directories doc/doxygen/LaTeX and + subdirectories. To generate printable versions, you need a latex + installation. However, the present size of this API information is + about 1500 pages, so you may not want to print it, and rather rely + on the online version. The more interesting part of the + documentation to print would probably be the example programs, but + we don't presently have a way to do that apart from printing it + directly from the browser or by using the html2ps + program.

    • @@ -517,7 +526,9 @@ should be fairly portable.

    If no argument is given to --with-multithreading, then - POSIX is assumed. + POSIX is assumed. In other words, giving any particular value to this + flag is redundant. However, you still need to give this flag (with or + without value) upon configuration if you want to use multithreading.

    @@ -528,6 +539,15 @@ systems.

    +
  • +

    + --with-doxygen=...: usually, ./configure is + able to figure out the path to the doxygen program by itself. However, + if you have multiple versions installed and want to select a specific + one, then you may want to specify path and filename to this version by + using the --with-doxygen flag. +

    +
  • --enable-compat-blocker=...: the library offers @@ -646,6 +666,56 @@ deal.II. Presently supported are the following:

      +
    • +

      + deal.II can interface to the PETSc library. PETSc's + main strength is to provide lots of functions for linear algebra, among + several other things. It comes with implementations of a variety of + linear solvers, as well as various different sparse and dense matrix and + vector formats, for which deal.II has wrapper classes + that provide almost the same interfaces as the built-in + deal.II linear algebra classes. The main advantage of + PETSc is the variety of its algorithms, and that all of them can work in + a parallel setting, i.e. matrices and vectors can be distributed across + a cluster of computers that communicate via MPI. This makes PETSc the + choice of linear algrebra implementations for very large problems that + do not fit into a single computer's memory or have run-times that are + too long for a single computer. At present, our interfaces are only + wrappers for vector and matrix formats, as well as to their solver and + preconditioner classes. However, we plan to extend this to a tighter + coupling in the future. +

      + +

      + The use of PETSc is optional, since deal.II comes + with a complete implementation of linear algebra classes + itself. However, if you wish to use the PETSc wrappers, you can do so by + having a PETSc installation around at the time of calling + ./configure. PETSc usually requires you to set the + environment variables PETSC_DIR and PETSC_ARCH + to a path to PETSc and denoting the architecture for which PETSc is + compiled. If these environment variables are set, then + deal.II will pick them up during configuration, and + store them. It will then also recognize that PETSc shall be used, and + enable the wrapper classes (they are disabled by default, if PETSc is + unavailable). However, you can override the values of these environment + variablaes by using the --with-petsc=DIR and + --with-mpi-arch=ARCH switches to ./configure. +

      + +

      + Note that in order to use PETSc with deal.II, you + need to have at least PETSc version 2.1.7 installed. Version 2.1.6 may + work in most cases, but you will get some (harmless) warnings during + compilation. Also, during testing with this version, we discovered a + serious bug in the TCQMR linear solver which basically renders it + useless. All these problems have been reported and are supposed to be + fixed in 2.1.7. Versions prior to 2.1.6 are likely not to work, but have + not been tested. +

      + +
    • It is possible to use some subroutines from the @@ -749,7 +819,7 @@ the homepage is appreciated.

    - Note that since our institute is evaluated at regular intervals, + Note that since our institutes are evaluated at regular intervals, we are interested in documenting the use of the programs and libraries we create. We are therefore interested in collecting publications with results obtained with the aid of these libraries diff --git a/deal.II/lac/Makefile b/deal.II/lac/Makefile index 64fca06233..721e2025ec 100644 --- a/deal.II/lac/Makefile +++ b/deal.II/lac/Makefile @@ -58,6 +58,12 @@ endif ifneq ($(GXX-VERSION),compaq_cxx) deplibs.g = $(lib-base.g) $(LIBHSL) deplibs.o = $(lib-base.o) $(LIBHSL) + + ifeq ($(USE_CONTRIB_PETSC),yes) + deplibs.g += $(lib-contrib-petsc.g) + deplibs.o += $(lib-contrib-petsc.o) + endif + else deplibs.g = deplibs.o = diff --git a/deal.II/lac/include/lac/block_sparse_matrix.h b/deal.II/lac/include/lac/block_sparse_matrix.h index dadf85544c..2e99142247 100644 --- a/deal.II/lac/include/lac/block_sparse_matrix.h +++ b/deal.II/lac/include/lac/block_sparse_matrix.h @@ -476,19 +476,20 @@ class BlockSparseMatrix : public Subscriptor /** * Add matrix scaled by - * factor to this matrix. The - * function throws an error if - * the sparsity patterns of the - * two involved matrices do not - * point to the same object, - * since in this case the + * factor to this matrix, + * i.e. the matrix factor*matrix + * is added to this. This + * function throws an error if the + * sparsity patterns of the two involved + * matrices do not point to the same + * object, since in this case the * operation is cheaper. * - * The source matrix may be a - * matrix of arbitrary type, as - * long as its data type is - * convertible to the data type - * of this matrix. + * The source matrix may be a sparse + * matrix over an arbitrary underlying + * scalar type, as long as its data type + * is convertible to the data type of + * this matrix. */ template void add_scaled (const number factor, diff --git a/deal.II/lac/include/lac/block_vector.h b/deal.II/lac/include/lac/block_vector.h index 834d51bfcd..60253849ee 100644 --- a/deal.II/lac/include/lac/block_vector.h +++ b/deal.II/lac/include/lac/block_vector.h @@ -968,6 +968,15 @@ class BlockVector * some time. */ bool all_zero () const; + /** + * Return @p{true} if the vector has no + * negative entries, i.e. all entries are + * zero or positive. This function is + * used, for example, to check whether + * refinement indicators are really all + * positive (or zero). + */ + bool is_non_negative () const; /** * @name 2: Data-Access diff --git a/deal.II/lac/include/lac/block_vector.templates.h b/deal.II/lac/include/lac/block_vector.templates.h index 84c494fb2d..1abfbc6f1b 100644 --- a/deal.II/lac/include/lac/block_vector.templates.h +++ b/deal.II/lac/include/lac/block_vector.templates.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -148,14 +148,27 @@ void BlockVector::clear () template -bool BlockVector::all_zero () const +bool +BlockVector::all_zero () const { - bool result = true; for (unsigned int i=0;i +bool +BlockVector::is_non_negative () const +{ + for (unsigned int i=0;i */ class const_iterator { - private: - public: /** * Constructor. @@ -204,7 +202,8 @@ class FullMatrix : public Table<2,number> * matrix as a rectangular * matrix. */ - FullMatrix (const unsigned int rows, const unsigned int cols); + FullMatrix (const unsigned int rows, + const unsigned int cols); /** * Copy constructor. This @@ -387,10 +386,29 @@ class FullMatrix : public Table<2,number> FullMatrix & operator /= (const double factor); /** + * Add matrix scaled by + * factor to this matrix, + * i.e. the matrix factor*matrix + * is added to this. + * + * The source matrix may be a full matrix + * over an arbitrary underlying scalar + * type, as long as its data type is + * convertible to the data type of this + * matrix. + */ + template + void add_scaled (const number factor, + const FullMatrix &matrix); + + /** * Weighted addition. The matrix * s*B is added to this. * - * $A += sB$ + * This function is deprecated. Use + * add_scaled instead, since + * this has the same interface as the + * other matrix classes in the library. */ template void add (const number s, @@ -522,6 +540,9 @@ class FullMatrix : public Table<2,number> * * if (!adding) * $w = A*v$ + * + * Source and destination must + * not be the same vector. */ template void vmult (Vector &w, @@ -532,6 +553,9 @@ class FullMatrix : public Table<2,number> * Transpose * matrix-vector-multiplication. * See vmult() above. + * + * Source and destination must + * not be the same vector. */ template void Tvmult (Vector &w, @@ -695,7 +719,7 @@ class FullMatrix : public Table<2,number> const number omega = 1.) const; /** - * $A(i,1-n)+=s*A(j,1-n)$. + * $A(i,1...n)+=s*A(j,1...n)$. * Simple addition of rows of this */ void add_row (const unsigned int i, @@ -703,7 +727,7 @@ class FullMatrix : public Table<2,number> const unsigned int j); /** - * $A(i,1-n)+=s*A(j,1-n)+t*A(k,1-n)$. + * $A(i,1...n)+=s*A(j,1...n)+t*A(k,1...n)$. * Multiple addition of rows of this. */ void add_row (const unsigned int i, @@ -711,7 +735,7 @@ class FullMatrix : public Table<2,number> const number t, const unsigned int k); /** - * $A(1-n,i)+=s*A(1-n,j)$. + * $A(1...n,i)+=s*A(1...n,j)$. * Simple addition of columns of this. */ void add_col (const unsigned int i, @@ -719,7 +743,7 @@ class FullMatrix : public Table<2,number> const unsigned int j); /** - * $A(1-n,i)+=s*A(1-n,j)+t*A(1-n,k)$. + * $A(1...n,i)+=s*A(1...n,j)+t*A(1...n,k)$. * Multiple addition of columns of this. */ void add_col (const unsigned int i, @@ -727,21 +751,21 @@ class FullMatrix : public Table<2,number> const number t, const unsigned int k); /** - * Swap A(i,1-n) <-> A(j,1-n). + * Swap A(i,1...n) <-> A(j,1...n). * Swap rows i and j of this */ void swap_row (const unsigned int i, const unsigned int j); /** - * Swap A(1-n,i) <-> A(1-n,j). + * Swap A(1...n,i) <-> A(1...n,j). * Swap columns i and j of this */ void swap_col (const unsigned int i, const unsigned int j); /** - * A(i,i)+=B(i,1-n). Addition of complete + * A(i,i)+=B(i,1...n). Addition of complete * rows of B to diagonal-elements of this ;

    * ( i = 1 ... m ) */ @@ -758,13 +782,17 @@ class FullMatrix : public Table<2,number> void diagadd (const number s); /** - * w=b-A*v. - * Residual calculation , returns - * the l2-norm |w|. + * dst=b-A*x. Residual calculation, + * returns the l2-norm + * |dst|. + * + * Source x and destination + * dst must not be the same + * vector. */ template - double residual (Vector &w, - const Vector &v, + double residual (Vector &dst, + const Vector &x, const Vector &b) const; /** @@ -941,7 +969,11 @@ class FullMatrix : public Table<2,number> int, << "This function is not implemented for the given" << " matrix dimension " << arg1); - + /** + * Exception + */ + DeclException0 (ExcSourceEqualsDestination); + friend class Accessor; }; diff --git a/deal.II/lac/include/lac/full_matrix.templates.h b/deal.II/lac/include/lac/full_matrix.templates.h index cf3854ec89..6244b79fe5 100644 --- a/deal.II/lac/include/lac/full_matrix.templates.h +++ b/deal.II/lac/include/lac/full_matrix.templates.h @@ -136,6 +136,8 @@ FullMatrix::vmult (Vector& dst, Assert(dst.size() == m(), ExcDimensionMismatch(dst.size(), m())); Assert(src.size() == n(), ExcDimensionMismatch(src.size(), n())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + if ((n()==3) && (m()==3)) { number2 s; @@ -304,6 +306,8 @@ void FullMatrix::Tvmult (Vector &dst, Assert(dst.size() == n(), ExcDimensionMismatch(dst.size(), n())); Assert(src.size() == m(), ExcDimensionMismatch(src.size(), m())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + const unsigned int size_m = m(), size_n = n(); @@ -342,6 +346,8 @@ double FullMatrix::residual (Vector& dst, Assert(src.size() == n(), ExcDimensionMismatch(src.size(), n())); Assert(right.size() == m(), ExcDimensionMismatch(right.size(), m())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + number2 s, res = 0.; const unsigned int size_m = m(), size_n = n(); @@ -743,8 +749,8 @@ FullMatrix::print (std::ostream &s, template template void -FullMatrix::add (const number s, - const FullMatrix &src) +FullMatrix::add_scaled (const number s, + const FullMatrix &src) { Assert (this->data() != 0, ExcEmptyMatrix()); @@ -755,114 +761,114 @@ FullMatrix::add (const number s, const number2* srcval = src.data(); if ((n()==3) && (m()==3)) - { - val[0] += s * srcval[0]; - val[1] += s * srcval[1]; - val[2] += s * srcval[2]; - val[3] += s * srcval[3]; - val[4] += s * srcval[4]; - val[5] += s * srcval[5]; - val[6] += s * srcval[6]; - val[7] += s * srcval[7]; - val[8] += s * srcval[8]; - } + { + val[0] += s * srcval[0]; + val[1] += s * srcval[1]; + val[2] += s * srcval[2]; + val[3] += s * srcval[3]; + val[4] += s * srcval[4]; + val[5] += s * srcval[5]; + val[6] += s * srcval[6]; + val[7] += s * srcval[7]; + val[8] += s * srcval[8]; + } else if ((n()==4) && (m()==4)) - { - val[0] += s * srcval[0]; - val[1] += s * srcval[1]; - val[2] += s * srcval[2]; - val[3] += s * srcval[3]; - val[4] += s * srcval[4]; - val[5] += s * srcval[5]; - val[6] += s * srcval[6]; - val[7] += s * srcval[7]; - val[8] += s * srcval[8]; - val[9] += s * srcval[9]; - val[10] += s * srcval[10]; - val[11] += s * srcval[11]; - val[12] += s * srcval[12]; - val[13] += s * srcval[13]; - val[14] += s * srcval[14]; - val[15] += s * srcval[15]; - } + { + val[0] += s * srcval[0]; + val[1] += s * srcval[1]; + val[2] += s * srcval[2]; + val[3] += s * srcval[3]; + val[4] += s * srcval[4]; + val[5] += s * srcval[5]; + val[6] += s * srcval[6]; + val[7] += s * srcval[7]; + val[8] += s * srcval[8]; + val[9] += s * srcval[9]; + val[10] += s * srcval[10]; + val[11] += s * srcval[11]; + val[12] += s * srcval[12]; + val[13] += s * srcval[13]; + val[14] += s * srcval[14]; + val[15] += s * srcval[15]; + } else if ((n()==8) && (m()==8)) - { - val[0] += s * srcval[0]; - val[1] += s * srcval[1]; - val[2] += s * srcval[2]; - val[3] += s * srcval[3]; - val[4] += s * srcval[4]; - val[5] += s * srcval[5]; - val[6] += s * srcval[6]; - val[7] += s * srcval[7]; - val[8] += s * srcval[8]; - val[9] += s * srcval[9]; - val[10] += s * srcval[10]; - val[11] += s * srcval[11]; - val[12] += s * srcval[12]; - val[13] += s * srcval[13]; - val[14] += s * srcval[14]; - val[15] += s * srcval[15]; - val[16] += s * srcval[16]; - val[17] += s * srcval[17]; - val[18] += s * srcval[18]; - val[19] += s * srcval[19]; - - val[20] += s * srcval[20]; - val[21] += s * srcval[21]; - val[22] += s * srcval[22]; - val[23] += s * srcval[23]; - val[24] += s * srcval[24]; - val[25] += s * srcval[25]; - val[26] += s * srcval[26]; - val[27] += s * srcval[27]; - val[28] += s * srcval[28]; - val[29] += s * srcval[29]; - - val[30] += s * srcval[30]; - val[31] += s * srcval[31]; - val[32] += s * srcval[32]; - val[33] += s * srcval[33]; - val[34] += s * srcval[34]; - val[35] += s * srcval[35]; - val[36] += s * srcval[36]; - val[37] += s * srcval[37]; - val[38] += s * srcval[38]; - val[39] += s * srcval[39]; - - val[40] += s * srcval[40]; - val[41] += s * srcval[41]; - val[42] += s * srcval[42]; - val[43] += s * srcval[43]; - val[44] += s * srcval[44]; - val[45] += s * srcval[45]; - val[46] += s * srcval[46]; - val[47] += s * srcval[47]; - val[48] += s * srcval[48]; - val[49] += s * srcval[49]; - - val[50] += s * srcval[50]; - val[51] += s * srcval[51]; - val[52] += s * srcval[52]; - val[53] += s * srcval[53]; - val[54] += s * srcval[54]; - val[55] += s * srcval[55]; - val[56] += s * srcval[56]; - val[57] += s * srcval[57]; - val[58] += s * srcval[58]; - val[59] += s * srcval[59]; - - val[60] += s * srcval[60]; - val[61] += s * srcval[61]; - val[62] += s * srcval[62]; - val[63] += s * srcval[63]; - } + { + val[0] += s * srcval[0]; + val[1] += s * srcval[1]; + val[2] += s * srcval[2]; + val[3] += s * srcval[3]; + val[4] += s * srcval[4]; + val[5] += s * srcval[5]; + val[6] += s * srcval[6]; + val[7] += s * srcval[7]; + val[8] += s * srcval[8]; + val[9] += s * srcval[9]; + val[10] += s * srcval[10]; + val[11] += s * srcval[11]; + val[12] += s * srcval[12]; + val[13] += s * srcval[13]; + val[14] += s * srcval[14]; + val[15] += s * srcval[15]; + val[16] += s * srcval[16]; + val[17] += s * srcval[17]; + val[18] += s * srcval[18]; + val[19] += s * srcval[19]; + + val[20] += s * srcval[20]; + val[21] += s * srcval[21]; + val[22] += s * srcval[22]; + val[23] += s * srcval[23]; + val[24] += s * srcval[24]; + val[25] += s * srcval[25]; + val[26] += s * srcval[26]; + val[27] += s * srcval[27]; + val[28] += s * srcval[28]; + val[29] += s * srcval[29]; + + val[30] += s * srcval[30]; + val[31] += s * srcval[31]; + val[32] += s * srcval[32]; + val[33] += s * srcval[33]; + val[34] += s * srcval[34]; + val[35] += s * srcval[35]; + val[36] += s * srcval[36]; + val[37] += s * srcval[37]; + val[38] += s * srcval[38]; + val[39] += s * srcval[39]; + + val[40] += s * srcval[40]; + val[41] += s * srcval[41]; + val[42] += s * srcval[42]; + val[43] += s * srcval[43]; + val[44] += s * srcval[44]; + val[45] += s * srcval[45]; + val[46] += s * srcval[46]; + val[47] += s * srcval[47]; + val[48] += s * srcval[48]; + val[49] += s * srcval[49]; + + val[50] += s * srcval[50]; + val[51] += s * srcval[51]; + val[52] += s * srcval[52]; + val[53] += s * srcval[53]; + val[54] += s * srcval[54]; + val[55] += s * srcval[55]; + val[56] += s * srcval[56]; + val[57] += s * srcval[57]; + val[58] += s * srcval[58]; + val[59] += s * srcval[59]; + + val[60] += s * srcval[60]; + val[61] += s * srcval[61]; + val[62] += s * srcval[62]; + val[63] += s * srcval[63]; + } else - { - const unsigned int size = n()*m(); - for (unsigned int i=0; i @@ -915,6 +921,19 @@ void FullMatrix::Tadd (const FullMatrix &src, +template +template +void +FullMatrix::add (const number s, + const FullMatrix &src) +{ + // this function is deprecated. forward to + // the other one + add_scaled (s, src); +} + + + template template void diff --git a/deal.II/lac/include/lac/petsc_full_matrix.h b/deal.II/lac/include/lac/petsc_full_matrix.h new file mode 100644 index 0000000000..40df615597 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_full_matrix.h @@ -0,0 +1,56 @@ +//---------------------------- petsc_full_matrix.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_full_matrix.h --------------------------- +#ifndef __deal2__petsc_full_matrix_h +#define __deal2__petsc_full_matrix_h + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + + +namespace PETScWrappers +{ +/** + * Implementation of a sequential dense matrix class based on PETSC. All the + * functionality is actually in the base class, except for the calls to + * generate a sequential dense matrix. This is possible since PETSc only works + * on an abstract matrix type and internally distributes to functions that do + * the actual work depending on the actual matrix type (much like using + * virtual functions). Only the functions creating a matrix of specific type + * differ, and are implemented in this particular class. + * + * @author Wolfgang Bangerth, 2004 + */ + class FullMatrix : public MatrixBase + { + public: + /** + * Create a full matrix of dimensions + * @p{m} times @p{n}. + */ + FullMatrix (const unsigned int m, + const unsigned int n); + }; +} + +#endif // DEAL_II_USE_PETSC + +/*---------------------------- petsc_full_matrix.h ---------------------------*/ + +#endif +/*---------------------------- petsc_full_matrix.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_matrix_base.h b/deal.II/lac/include/lac/petsc_matrix_base.h new file mode 100644 index 0000000000..223398e078 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_matrix_base.h @@ -0,0 +1,428 @@ +//---------------------------- petsc_matrix_base.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_matrix_base.h --------------------------- +#ifndef __deal2__petsc_matrix_base_h +#define __deal2__petsc_matrix_base_h + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + +namespace PETScWrappers +{ + // forward declaration + class VectorBase; + + +/** + * Base class for all matrix classes that are implemented on top of the PETSc + * matrix types. Since in PETSc all matrix types (i.e. sequential and + * parallel, sparse, blocked, etc.) are built by filling the contents of an + * abstract object that is only referenced through a pointer of a type that is + * independent of the actual matrix type, we can implement almost all + * functionality of matrices in this base class. Derived classes will then only + * have to provide the functionality to create one or the other kind of + * matrix. + * + * The interface of this class is modeled after the existing + * @ref{SparseMatrix} class in deal.II. It has almost the same member + * functions, and is often exchangable. However, since PETSc only supports a + * single scalar type (either double, float, or a complex data type), it is + * not templated, and only works with whatever your PETSc installation has + * defined the data type @p{PetscScalar} to. + * + * Note that PETSc only guarantees that operations do what you expect if the + * functions @p{MatAssemblyBegin} and @p{MatAssemblyEnd} have been called + * after matrix assembly. Therefore, you need to call + * @ref{SparseMatrix::compress} before you actually use the matrix. This also + * calls @p{MatCompress} that compresses the storage format for sparse + * matrices by discarding unused elements. PETSc allows to continue with + * assembling the matrix after calls to these functions, but since there are + * no more free entries available after that any more, it is better to only + * call @ref{SparseMatrix::compress} once at the end of the assembly stage and + * before the matrix is actively used. + * + * @author Wolfgang Bangerth, 2004 + */ + class MatrixBase + { + public: + /** + * Default constructor. + */ + MatrixBase (); + + /** + * Destructor. Made virtual so that one + * can use pointers to this class. + */ + virtual ~MatrixBase (); + + /** + * Set all matrix entries to zero, but + * retain the sparsity pattern. + */ + void reinit (); + + /** + * Set the element (i,j) + * to value. Throws an + * error if the entry does not + * exist. Still, it is allowed to + * store zero values in + * non-existent fields. + */ + void set (const unsigned int i, + const unsigned int j, + const PetscScalar value); + + /** + * Add value to the + * element (i,j). Throws + * an error if the entry does not + * exist. Still, it is allowed to + * store zero values in + * non-existent fields. + */ + void add (const unsigned int i, + const unsigned int j, + const PetscScalar value); + + /** + * PETSc matrices store their own + * sparsity patterns. So, in analogy to + * our own @ref{SparsityPattern} class, + * this function compresses the + * sparsity pattern and allows the + * resulting matrix to be used in all + * other operations where before only + * assembly functions were + * allowed. This function must + * therefore be called once you have + * assembled the matrix. + */ + void compress (); + + /** + * Return the value of the entry + * (i,j). This may be an + * expensive operation and you should + * always take care where to call this + * function. In contrast to the + * respective function in the + * @p{MatrixBase} class, we don't + * throw an exception if the respective + * entry doesn't exist in the sparsity + * pattern of this class, since PETSc + * does not transmit this information. + * + * This function is therefore exactly + * equivalent to the @p{el()} function. + */ + PetscScalar operator () (const unsigned int i, + const unsigned int j) const; + + /** + * Return the value of the matrix entry + * (i,j). If this entry does not + * exist in the sparsity pattern, then + * zero is returned. While this may be + * convenient in some cases, note that + * it is simple to write algorithms + * that are slow compared to an optimal + * solution, since the sparsity of the + * matrix is not used. + */ + PetscScalar el (const unsigned int i, + const unsigned int j) const; + + /** + * Return the number of rows in this + * matrix. + */ + unsigned int m () const; + + /** + * Return the number of columns in this + * matrix. + */ + unsigned int n () const; + + /** + * Return the number of nonzero + * elements of this + * matrix. Actually, it returns + * the number of entries in the + * sparsity pattern; if any of + * the entries should happen to + * be zero, it is counted anyway. + */ + unsigned int n_nonzero_elements () const; + + /** + * Return the l1-norm of the matrix, that is + * $|M|_1=max_{all columns j}\sum_{all + * rows i} |M_ij|$, + * (max. sum of columns). + * This is the + * natural matrix norm that is compatible + * to the l1-norm for vectors, i.e. + * $|Mv|_1\leq |M|_1 |v|_1$. + * (cf. Haemmerlin-Hoffmann: + * Numerische Mathematik) + */ + PetscReal l1_norm () const; + + /** + * Return the linfty-norm of the + * matrix, that is + * $|M|_infty=max_{all rows i}\sum_{all + * columns j} |M_ij|$, + * (max. sum of rows). + * This is the + * natural matrix norm that is compatible + * to the linfty-norm of vectors, i.e. + * $|Mv|_infty \leq |M|_infty |v|_infty$. + * (cf. Haemmerlin-Hoffmann: + * Numerische Mathematik) + */ + PetscReal linfty_norm () const; + + /** + * Return the frobenius norm of the + * matrix, i.e. the square root of the + * sum of squares of all entries in the + * matrix. + */ + PetscReal frobenius_norm () const; + + /** + * Multiply the entire matrix by a + * fixed factor. + */ + MatrixBase & operator *= (const PetscScalar factor); + + /** + * Divide the entire matrix by a + * fixed factor. + */ + MatrixBase & operator /= (const PetscScalar factor); + + /** + * Matrix-vector multiplication: + * let dst = M*src with + * M being this matrix. + * + * Source and destination must + * not be the same vector. + */ + void vmult (VectorBase &dst, + const VectorBase &src) const; + + /** + * Matrix-vector multiplication: let + * dst = MT*src with + * M being this matrix. This + * function does the same as vmult() + * but takes the transposed matrix. + * + * Source and destination must + * not be the same vector. + */ + void Tvmult (VectorBase &dst, + const VectorBase &src) const; + + /** + * Adding Matrix-vector + * multiplication. Add + * M*src on dst + * with M being this + * matrix. + * + * Source and destination must + * not be the same vector. + */ + void vmult_add (VectorBase &dst, + const VectorBase &src) const; + + /** + * Adding Matrix-vector + * multiplication. Add + * MT*src to + * dst with M being + * this matrix. This function + * does the same as vmult_add() + * but takes the transposed + * matrix. + * + * Source and destination must + * not be the same vector. + */ + void Tvmult_add (VectorBase &dst, + const VectorBase &src) const; + + /** + * Return the square of the norm + * of the vector $v$ with respect + * to the norm induced by this + * matrix, + * i.e. $\left(v,Mv\right)$. This + * is useful, e.g. in the finite + * element context, where the + * $L_2$ norm of a function + * equals the matrix norm with + * respect to the mass matrix of + * the vector representing the + * nodal values of the finite + * element function. + * + * Obviously, the matrix needs to + * be quadratic for this operation. + * + * The implementation of this function + * is not as efficient as the one in + * the @p{MatrixBase} class used in + * deal.II (i.e. the original one, not + * the PETSc wrapper class) since PETSc + * doesn't support this operation and + * needs a temporary vector. + */ + PetscScalar matrix_norm_square (const VectorBase &v) const; + + /** + * Compute the matrix scalar + * product $\left(u,Mv\right)$. + * + * The implementation of this function + * is not as efficient as the one in + * the @p{MatrixBase} class used in + * deal.II (i.e. the original one, not + * the PETSc wrapper class) since PETSc + * doesn't support this operation and + * needs a temporary vector. + */ + PetscScalar matrix_scalar_product (const VectorBase &u, + const VectorBase &v) const; + + /** + * Compute the residual of an + * equation Mx=b, where + * the residual is defined to be + * r=b-Mx. Write the + * residual into + * dst. The + * l2 norm of + * the residual vector is + * returned. + * + * Source x and destination + * dst must not be the same + * vector. + */ + PetscScalar residual (VectorBase &dst, + const VectorBase &x, + const VectorBase &b) const; + + /** + * Conversion operator to gain access + * to the underlying PETSc type. If you + * do this, you cut this class off some + * information it may need, so this + * conversion operator should only be + * used if you know what you do. In + * particular, it should only be used + * for read-only operations into the + * matrix. + */ + operator const Mat () const; + + /** + * Exception + */ + DeclException1 (ExcPETScError, + int, + << "An error with error number " << arg1 + << " occured while calling a PETSc function"); + /** + * Exception + */ + DeclException0 (ExcSourceEqualsDestination); + + protected: + /** + * A generic matrix object in + * PETSc. The actual type, a sparse + * matrix, is set in the constructor. + */ + Mat matrix; + + /** + * PETSc doesn't allow to mix additions + * to matrix entries and overwriting + * them (to make synchronisation of + * parallel computations + * simpler). Since the interface of the + * existing classes don't support the + * notion of not interleaving things, + * we have to emulate this + * ourselves. The way we do it is to, + * for each access operation, store + * whether it is an insertion or an + * addition. If the previous one was of + * different type, then we first have + * to flush the PETSc buffers; + * otherwise, we can simply go on. + * + * The following structure and variable + * declare and store the previous + * state. + */ + struct LastAction + { + enum Values { none, insert, add }; + }; + + /** + * Store whether the last action was a + * write or add operation. + */ + LastAction::Values last_action; + }; + + + + +// -------------------------- inline and template functions ---------------------- + + inline + PetscScalar + MatrixBase::operator() (const unsigned int i, + const unsigned int j) const + { + return el(i,j); + } + + +} + +#endif // DEAL_II_USE_PETSC + + +/*---------------------------- petsc_matrix_base.h ---------------------------*/ + +#endif +/*---------------------------- petsc_matrix_base.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_precondition.h b/deal.II/lac/include/lac/petsc_precondition.h new file mode 100644 index 0000000000..e6f84de8d5 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_precondition.h @@ -0,0 +1,437 @@ +//---------------------------- petsc_precondition.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_precondition.h --------------------------- +#ifndef __deal2__petsc_precondition_h +#define __deal2__petsc_precondition_h + +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + +namespace PETScWrappers +{ + // forward declarations + class MatrixBase; + class VectorBase; + class SolverBase; + + +/** + * Base class for preconditioner classes using the PETSc functionality. The + * classes in this hierarchy don't do a whole lot, except for providing a + * function that sets the preconditioner and certain parameters on the + * preconditioning context of the solver. These classes are basically here + * only to allow a similar interface than already used for the deal.II solver + * and preconditioner classes. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionerBase + { + public: + /** + * Constructor. Take a pointer to the + * matrix from which the preconditioner + * shall be constructed. + */ + PreconditionerBase (const MatrixBase &matrix); + + /** + * Destructor. + */ + virtual ~PreconditionerBase (); + + /** + * Exception + */ + DeclException1 (ExcPETScError, + int, + << "An error with error number " << arg1 + << " occured while calling a PETSc function"); + + protected: + /** + * A pointer to the matrix that acts as + * a preconditioner. + */ + const Mat matrix; + + /** + * Conversion operator to get a + * representation of the matrix that + * represents this preconditioner. We + * use this inside the actual solver, + * where we need to pass this matrix to + * the PETSc solvers. + */ + operator const Mat () const; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is requested by + * the derived class. + */ + virtual void set_preconditioner_type (PC &pc) const = 0; + + /** + * Make the solver class a friend, + * since it needs to call the + * conversion operator. + */ + friend class SolverBase; + }; + + + +/** + * A class that implements the interface to use the PETSc Jacobi + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionJacobi : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + {}; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionJacobi (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + + + +/** + * A class that implements the interface to use the PETSc SOR + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionSOR : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the damping parameter + * to one. + */ + AdditionalData (const double omega = 1); + + /** + * Relaxation parameter. + */ + double omega; + }; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionSOR (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + + + +/** + * A class that implements the interface to use the PETSc SSOR + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionSSOR : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the damping parameter + * to one. + */ + AdditionalData (const double omega = 1); + + /** + * Relaxation parameter. + */ + double omega; + }; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionSSOR (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + + + +/** + * A class that implements the interface to use the PETSc Eisenstat + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionEisenstat : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the damping parameter + * to one. + */ + AdditionalData (const double omega = 1); + + /** + * Relaxation parameter. + */ + double omega; + }; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionEisenstat (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + + + +/** + * A class that implements the interface to use the PETSc Incomplete Cholesky + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionICC : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the fill-in parameter + * to zero. + */ + AdditionalData (const unsigned int levels = 0); + + /** + * Fill-in parameter. + */ + unsigned int levels; + }; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionICC (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + + + +/** + * A class that implements the interface to use the PETSc ILU + * preconditioner. + * + * @author Wolfgang Bangerth, 2004 + */ + class PreconditionILU : public PreconditionerBase + { + public: + /** + * Standardized data struct to + * pipe additional flags to the + * preconditioner. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the fill-in parameter + * to zero. + */ + AdditionalData (const unsigned int levels = 0); + + /** + * Fill-in parameter. + */ + unsigned int levels; + }; + + /** + * Constructor. Take the matrix which + * is used to form the preconditioner, + * and additional flags if there are + * any. + */ + PreconditionILU (const MatrixBase &matrix, + const AdditionalData &additional_data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular preconditioner. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Preconditioner context + * object, and sets the type of + * preconditioner that is appropriate + * for the present class. + */ + virtual void set_preconditioner_type (PC &pc) const; + }; + +} + + +#endif // DEAL_II_USE_PETSC + +/*---------------------------- petsc_precondition.h ---------------------------*/ + +#endif +/*---------------------------- petsc_precondition.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_solver.h b/deal.II/lac/include/lac/petsc_solver.h new file mode 100644 index 0000000000..378e6e8a15 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_solver.h @@ -0,0 +1,802 @@ +//---------------------------- petsc_solver.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_solver.h --------------------------- +#ifndef __deal2__petsc_solver_h +#define __deal2__petsc_solver_h + +#include +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + +namespace PETScWrappers +{ + // forward declarations + class MatrixBase; + class VectorBase; + class PreconditionerBase; + + +/** + * Base class for solver classes using the PETSc solvers. Since solvers in + * PETSc are selected based on flags passed to a generic solver object, + * basically all the actual solver calls happen in this class, and derived + * classes simply set the right flags to select one solver or another, or to + * set certain parameters for individual solvers. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverBase + { + public: + /** + * Constructor. Takes the solver + * control object and the MPI + * communicator over which parallel + * computations are to happen. + */ + SolverBase (SolverControl &cn, + MPI_Comm &mpi_communicator); + + /** + * Destructor. + */ + virtual ~SolverBase (); + + /** + * Solve the linear system + * Ax=b. Depending on the + * information provided by derived + * classes and the object passed as a + * preconditioner, one of the linear + * solvers and preconditioners of PETSc + * is chosen. + */ + void + solve (const MatrixBase &A, + VectorBase &x, + const VectorBase &b, + const PreconditionerBase &preconditioner) const; + + + /** + * Access to object that controls + * convergence. + */ + SolverControl & control() const; + + /** + * Exception + */ + DeclException1 (ExcPETScError, + int, + << "An error with error number " << arg1 + << " occured while calling a PETSc function"); + + protected: + + /** + * Reference to the object that + * controls convergence of the + * iterative solver. In fact, for these + * PETSc wrappers, PETSc does so + * itself, but we copy the data from + * this object before starting the + * solution process, and copy the data + * back into it afterwards. + */ + SolverControl &solver_control; + + /** + * Copy of the MPI communicator object + * to be used for the solver. + */ + MPI_Comm mpi_communicator; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + * requested by the derived class. + */ + virtual void set_solver_type (KSP &ksp) const = 0; + + private: + /** + * A function that is used in PETSc as + * a callback to check on + * convergence. It takes the + * information provided from PETSc and + * checks it against deal.II's own + * SolverControl objects to see if + * convergence has been reached. + */ + static + int + convergence_test (KSP ksp, + const int iteration, + const double residual_norm, + KSPConvergedReason *reason, + void *solver_control); + }; + + + +/** + * An implementation of the solver interface using the PETSc Richardson + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverRichardson : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + { + /** + * Constructor. By default, + * set the damping parameter + * to one. + */ + AdditionalData (const double omega = 1); + + /** + * Relaxation parameter. + */ + double omega; + }; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverRichardson (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc Chebychev + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverChebychev : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverChebychev (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc CG + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverCG : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverCG (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc BiCG + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverBiCG : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverBiCG (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc GMRES + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverGMRES : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + { + /** + * Constructor. By default, set the + * number of temporary vectors to + * 30, i.e. do a restart every 30 + * iterations. + */ + AdditionalData (const unsigned int restart_parameter = 30); + + /** + * Maximum number of + * tmp vectors. + */ + unsigned int restart_parameter; + }; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverGMRES (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc BiCGStab + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverBicgstab : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverBicgstab (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc CG Squared + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverCGS : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverCGS (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc TFQMR + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverTFQMR : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverTFQMR (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + + +/** + * An implementation of the solver interface using the PETSc TFQMR-2 solver + * (called TCQMR in PETSc). Note that this solver had a serious bug in + * versions up to and including PETSc 2.1.6, in that it did not check + * convergence and always returned an error code. Thus, this class will abort + * with an error indicating failure to converge with PETSc 2.1.6 and + * prior. This should be fixed in later versions of PETSc, though. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverTCQMR : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverTCQMR (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc CR + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverCR : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverCR (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + + + +/** + * An implementation of the solver interface using the PETSc Least Squares + * solver. + * + * @author Wolfgang Bangerth, 2004 + */ + class SolverLSQR : public SolverBase + { + public: + /** + * Standardized data struct to + * pipe additional data to the + * solver. + */ + struct AdditionalData + {}; + + /** + * Constructor. In contrast to + * deal.II's own solvers, there is no + * need to give a vector memory + * object. However, PETSc solvers want + * to have an MPI communicator context + * over which computations are + * parallelized. By default, + * @p{PETSC_COMM_SELF} is used here, + * but you can change this. Note that + * for single processor (non-MPI) + * versions, this parameter does not + * have any effect. + * + * The last argument takes a structure + * with additional, solver dependent + * flags for tuning. + */ + SolverLSQR (SolverControl &cn, + MPI_Comm &mpi_communicator = PETSC_COMM_SELF, + const AdditionalData &data = AdditionalData()); + + protected: + /** + * Store a copy of the flags for this + * particular solver. + */ + const AdditionalData additional_data; + + /** + * Function that takes a Krylov + * Subspace Solver context object, and + * sets the type of solver that is + *appropriate for this class. + */ + virtual void set_solver_type (KSP &ksp) const; + }; + +} + + +#endif // DEAL_II_USE_PETSC + +/*---------------------------- petsc_solver.h ---------------------------*/ + +#endif +/*---------------------------- petsc_solver.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_sparse_matrix.h b/deal.II/lac/include/lac/petsc_sparse_matrix.h new file mode 100644 index 0000000000..a7abf35061 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_sparse_matrix.h @@ -0,0 +1,111 @@ +//---------------------------- petsc_sparse_matrix.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_sparse_matrix.h --------------------------- +#ifndef __deal2__petsc_sparse_matrix_h +#define __deal2__petsc_sparse_matrix_h + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + +#include + + + +namespace PETScWrappers +{ +/** + * Implementation of a sequential sparse matrix class based on PETSC. All the + * functionality is actually in the base class, except for the calls to + * generate a sequential sparse matrix. This is possible since PETSc only works + * on an abstract matrix type and internally distributes to functions that do + * the actual work depending on the actual matrix type (much like using + * virtual functions). Only the functions creating a matrix of specific type + * differ, and are implemented in this particular class. + * + * @author Wolfgang Bangerth, 2004 + */ + class SparseMatrix : public MatrixBase + { + public: + /** + * Create a sparse matrix of dimensions + * m times n, with an + * initial guess of + * n_nonzero_per_row nonzero + * elements per row. PETSc is able to + * cope with the situation that more + * than this number of elements is + * later allocated for a row, but this + * involves copying data, and is thus + * expensive. + * + * The @p{is_symmetric} flag determines + * whether we should tell PETSc that + * the matrix is going to be symmetric + * (as indicated by the call + * @p{MatSetOption(mat,MAT_SYMMETRIC)}. Note + * that the PETSc documentation states + * that one cannot form an ILU + * decomposition of a matrix for which + * this flag has been set. The default + * value of this flag is @p{false}. + */ + SparseMatrix (const unsigned int m, + const unsigned int n, + const unsigned int n_nonzero_per_row, + const bool is_symmetric = false); + + /** + * Initialize a rectangular matrix with + * m rows and n + * columns. The maximal number of + * nonzero entries for each row + * separately is given by the + * row_lengths array. + * + * Just as for the other constructors: + * PETSc is able to cope with the + * situation that more than this number + * of elements is later allocated for a + * row, but this involves copying data, + * and is thus expensive. + * + * The @p{is_symmetric} flag determines + * whether we should tell PETSc that + * the matrix is going to be symmetric + * (as indicated by the call + * @p{MatSetOption(mat,MAT_SYMMETRIC)}. Note + * that the PETSc documentation states + * that one cannot form an ILU + * decomposition of a matrix for which + * this flag has been set. The default + * value of this flag is @p{false}. + */ + SparseMatrix (const unsigned int m, + const unsigned int n, + const std::vector &row_lengths, + const bool is_symmetric = false); + + }; +} + +#endif // DEAL_II_USE_PETSC + +/*---------------------------- petsc_sparse_matrix.h ---------------------------*/ + +#endif +/*---------------------------- petsc_sparse_matrix.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_vector.h b/deal.II/lac/include/lac/petsc_vector.h new file mode 100644 index 0000000000..df06e43adf --- /dev/null +++ b/deal.II/lac/include/lac/petsc_vector.h @@ -0,0 +1,155 @@ +//---------------------------- petsc_vector.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_vector.h --------------------------- +#ifndef __deal2__petsc_vector_h +#define __deal2__petsc_vector_h + +#include +#include +#include + +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + +namespace PETScWrappers +{ +/** + * Implementation of a sequential vector class based on PETSC. All the + * functionality is actually in the base class, except for the calls to + * generate a sequential vector. This is possible since PETSc only works on an + * abstract vector type and internally distributes to functions that do the + * actual work depending on the actual vector type (much like using virtual + * functions). Only the functions creating a vector of specific type differ, + * and are implemented in this particular class. + * + * @author Wolfgang Bangerth, 2004 + */ + class Vector : public VectorBase + { + public: + /** + * Default constructor. Initialize the + * vector as empty. + */ + Vector (); + + /** + * Constructor. Set dimension to + * @p{n} and initialize all + * elements with zero. + * + * The constructor is made explicit to + * avoid accidents like this: + * @p{v=0;}. Presumably, the user wants + * to set every element of the vector to + * zero, but instead, what happens is + * this call: @p{v=Vector(0);}, + * i.e. the vector is replaced by one of + * length zero. + */ + explicit Vector (const unsigned int n); + + /** + * Copy-constructor from deal.II + * vectors. Sets the dimension to that + * of the given vector, and copies all + * elements. + */ + template + explicit Vector (const ::Vector &v); + + /** + * Copy-constructor the + * values from a PETSc wrapper vector + * class. + */ + explicit Vector (const VectorBase &v); + + /** + * Set all components of the vector to + * the given number @p{s}. Simply pass + * this down to the base class, but we + * still need to declare this function + * to make the example given in the + * discussion about making the + * constructor explicit work. + */ + Vector & operator = (const PetscScalar s); + + /** + * Copy the values of a deal.II vector + * (as opposed to those of the PETSc + * vector wrapper class) into this + * object. + */ + template + Vector & operator = (const ::Vector &v); + + protected: + /** + * Create a vector of length @p{n}. For + * this class, we create a sequential + * vector. + */ + virtual void create_vector (const unsigned int n); + }; + + + +// ------------------ template and inline functions ------------- + + + template + Vector::Vector (const ::Vector &v) + { + int ierr + = VecCreateSeq (PETSC_COMM_SELF, v.size(), &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + VectorBase::operator = (v); + } + + + + inline + Vector & + Vector::operator = (const PetscScalar s) + { + VectorBase::operator = (s); + + return *this; + } + + + template + inline + Vector & + Vector::operator = (const ::Vector &v) + { + VectorBase::operator = (v); + + return *this; + } + +} + + +#endif // DEAL_II_USE_PETSC + +/*---------------------------- petsc_vector.h ---------------------------*/ + +#endif +/*---------------------------- petsc_vector.h ---------------------------*/ diff --git a/deal.II/lac/include/lac/petsc_vector_base.h b/deal.II/lac/include/lac/petsc_vector_base.h new file mode 100644 index 0000000000..0cb7e52d68 --- /dev/null +++ b/deal.II/lac/include/lac/petsc_vector_base.h @@ -0,0 +1,915 @@ +//---------------------------- petsc_vector_base.h --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- petsc_vector_base.h --------------------------- +#ifndef __deal2__petsc_vector_base_h +#define __deal2__petsc_vector_base_h + + +#include +#include +#include + +#ifdef DEAL_II_USE_PETSC + +#include + + + // forward declaration +template class Vector; + + +/** + * A namespace in which wrapper classes for PETSc objects reside. + * + * @author Wolfgang Bangerth, 2004 + */ +namespace PETScWrappers +{ + // forward declaration + class VectorBase; + + +/** + * A namespace for internal implementation details of the PETScWrapper + * members. + */ + namespace internal + { + /** + * Since access to PETSc vectors only + * goes through functions, rather than by + * obtaining a reference to a vector + * element, we need a wrapper class that + * acts as if it was a reference, and + * basically redirects all accesses (read + * and write) to member functions of this + * class. + * + * This class implements such a wrapper: + * it is initialized with a vector and an + * element within it, and has a + * conversion operator to extract the + * scalar value of this element. It also + * has a variety of assignment operator + * for writing to this one element. + */ + class VectorReference + { + private: + /** + * Constructor. It is made private so + * as to only allow the actual vector + * class to create it. + */ + VectorReference (const VectorBase &vector, + const unsigned int index); + + public: + /** + * Set the referenced element of the + * vector to s. + */ + const VectorReference & operator = (const PetscScalar &s) const; + + /** + * Add s to the referenced + * element of the vector. + */ + const VectorReference & operator += (const PetscScalar &s) const; + + /** + * Subtract s from the referenced + * element of the vector. + */ + const VectorReference & operator -= (const PetscScalar &s) const; + + /** + * Multiply the referenced element of + * the vector by s. + */ + const VectorReference & operator *= (const PetscScalar &s) const; + + /** + * Divide the referenced element of + * the vector by s. + */ + const VectorReference & operator /= (const PetscScalar &s) const; + + /** + * Convert the reference to an actual + * value, i.e. return the value of + * the referenced element of the + * vector. + */ + operator PetscScalar () const; + + /** + * Exception + */ + DeclException1 (ExcPETScError, + int, + << "An error with error number " << arg1 + << " occured while calling a PETSc function"); + private: + /** + * Point to the vector we are + * referencing. + */ + const VectorBase &vector; + + /** + * Index of the referenced element of + * the vector. + */ + const unsigned int index; + + /** + * Make the vector class a friend, so + * that it can create objects of the + * present type. + */ + friend class ::PETScWrappers::VectorBase; + }; + } + + +/** + * Base class for all vector classes that are implemented on top of the PETSc + * vector types. Since in PETSc all vector types (i.e. sequential and parallel + * ones) are built by filling the contents of an abstract object that is only + * referenced through a pointer of a type that is independent of the actual + * vector type, we can implement almost all functionality of vectors in this + * base class. Derived classes will then only have to provide the + * functionality to create one or the other kind of vector. + * + * The interface of this class is modeled after the existing @ref{Vector} + * class in deal.II. It has almost the same member functions, and is often + * exchangable. However, since PETSc only supports a single scalar type + * (either double, float, or a complex data type), it is not templated, and + * only works with whatever your PETSc installation has defined the data type + * @p{PetscScalar} to. + * + * Note that PETSc only guarantees that operations do what you expect if the + * functions @p{VecAssemblyBegin} and @p{VecAssemblyEnd} have been called + * after vector assembly. Therefore, you need to call @ref{Vector::compress} + * before you actually use the vector. + * + * @author Wolfgang Bangerth, 2004 + */ + class VectorBase + { + public: + /** + * Declare some of the standard types + * used in all containers. These types + * parallel those in the @p{C++} + * standard libraries @p{vector<...>} + * class. + */ + typedef PetscScalar value_type; + typedef size_t size_type; + + /** + * Default constructor. It doesn't do + * anything, derived classes will have + * to initialize the data. + */ + VectorBase (); + + /** + * Copy constructor. Sets the dimension + * to that of the given vector, and + * copies all elements. + */ + VectorBase (const VectorBase &v); + + /** + * Destructor + */ + virtual ~VectorBase (); + + /** + * Compress the underlying + * representation of the PETSc object, + * i.e. flush the buffers of the vector + * object if it has any. This function + * is necessary after writing into a + * vector element-by-element and before + * anything else can be done on it. + */ + void compress (); + + /** + * Change the dimension of the vector + * to @p{N}. It is unspecified how + * resizing the vector affects the + * memory allocation of this object; + * i.e., it is not guaranteed that + * resizing it to a smaller size + * actually also reduces memory + * consumption, or if for efficiency + * the same amount of memory is used + * for less data. + * + * On @p{fast==false}, the vector is + * filled by zeros. Otherwise, the + * elements are left an unspecified + * state. + */ + void reinit (const unsigned int N, + const bool fast=false); + + /** + * Change the dimension to that of the + * vector @p{V}. The same applies as + * for the other @p{reinit} function. + * + * The elements of @p{V} are not + * copied, i.e. this function is the + * same as calling @p{reinit (V.size(), + * fast)}. + */ + void reinit (const VectorBase &V, + const bool fast=false); + + /** + * Set all entries to zero. Equivalent + * to @p{v = 0}, but more obvious and + * faster. Note that this function + * does not change the size of the + * vector, unlike the STL's + * @p{vector<>::clear} function. + */ + void clear (); + + /** + * Set all components of the vector to + * the given number @p{s}. + */ + VectorBase & operator = (const PetscScalar s); + + /** + * Copy the given vector. Resize the + * present vector if necessary. + */ + VectorBase & operator = (const VectorBase &v); + + /** + * Copy the values of a deal.II vector + * (as opposed to those of the PETSc + * vector wrapper class) into this + * object. + */ + template + VectorBase & operator = (const ::Vector &v); + + /** + * Test for equality. This function + * assumes that the present vector and + * the one to compare with have the same + * size already, since comparing vectors + * of different sizes makes not much + * sense anyway. + */ + bool operator == (const VectorBase &v) const; + + /** + * Test for inequality. This function + * assumes that the present vector and + * the one to compare with have the same + * size already, since comparing vectors + * of different sizes makes not much + * sense anyway. + */ + bool operator != (const VectorBase &v) const; + + /** + * Return dimension of the vector. + */ + unsigned int size () const; + + /** + * Provide access to a given element, + * both read and write. + */ + internal::VectorReference + operator () (const unsigned int index); + + /** + * Provide read-only access to an + * element. + */ + PetscScalar + operator () (const unsigned int index) const; + + /** + * Return the scalar product of two + * vectors. The vectors must have the + * same size. + */ + PetscScalar operator * (const VectorBase &vec) const; + + /** + * Return square of the $l_2$-norm. + */ + PetscScalar norm_sqr () const; + + /** + * Mean value of the elements of + * this vector. + */ + PetscScalar mean_value () const; + + /** + * $l_1$-norm of the vector. + * The sum of the absolute values. + */ + PetscScalar l1_norm () const; + + /** + * $l_2$-norm of the vector. The + * square root of the sum of the + * squares of the elements. + */ + PetscScalar l2_norm () const; + + /** + * $l_p$-norm of the vector. The + * pth root of the sum of the pth + * powers of the absolute values + * of the elements. + */ + PetscScalar lp_norm (const PetscScalar p) const; + + /** + * Maximum absolute value of the + * elements. + */ + PetscScalar linfty_norm () const; + + /** + * Return whether the vector contains + * only elements with value zero. This + * function is mainly for internal + * consistency checks and should + * seldomly be used when not in debug + * mode since it uses quite some time. + */ + bool all_zero () const; + + /** + * Return @p{true} if the vector has no + * negative entries, i.e. all entries + * are zero or positive. This function + * is used, for example, to check + * whether refinement indicators are + * really all positive (or zero). + */ + bool is_non_negative () const; + + /** + * Multiply the entire vector by a + * fixed factor. + */ + VectorBase & operator *= (const PetscScalar factor); + + /** + * Divide the entire vector by a + * fixed factor. + */ + VectorBase & operator /= (const PetscScalar factor); + + /** + * Add the given vector to the present + * one. + */ + VectorBase & operator += (const VectorBase &V); + + /** + * Subtract the given vector from the + * present one. + */ + VectorBase & operator -= (const VectorBase &V); + + /** + * Addition of @p{s} to all + * components. Note that @p{s} is a + * scalar and not a vector. + */ + void add (const PetscScalar s); + + /** + * Simple vector addition, equal to the + * @p{operator +=}. + */ + void add (const VectorBase &V); + + /** + * Simple addition of a multiple of a + * vector, i.e. @p{*this += a*V}. + */ + void add (const PetscScalar a, const VectorBase &V); + + /** + * Multiple addition of scaled vectors, + * i.e. @p{*this += a*V+b*W}. + */ + void add (const PetscScalar a, const VectorBase &V, + const PetscScalar b, const VectorBase &W); + + /** + * Scaling and simple vector addition, + * i.e. + * @p{*this = s*(*this)+V}. + */ + void sadd (const PetscScalar s, + const VectorBase &V); + + /** + * Scaling and simple addition, i.e. + * @p{*this = s*(*this)+a*V}. + */ + void sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &V); + + /** + * Scaling and multiple addition. + */ + void sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &V, + const PetscScalar b, + const VectorBase &W); + + /** + * Scaling and multiple addition. + * @p{*this = s*(*this)+a*V + b*W + c*X}. + */ + void sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &V, + const PetscScalar b, + const VectorBase &W, + const PetscScalar c, + const VectorBase &X); + + /** + * Scale each element of this + * vector by the corresponding + * element in the argument. This + * function is mostly meant to + * simulate multiplication (and + * immediate re-assignment) by a + * diagonal scaling matrix. + */ + void scale (const VectorBase &scaling_factors); + + /** + * Assignment @p{*this = a*V}. + */ + void equ (const PetscScalar a, const VectorBase &V); + + /** + * Assignment @p{*this = a*V + b*W}. + */ + void equ (const PetscScalar a, const VectorBase &V, + const PetscScalar b, const VectorBase &W); + + /** + * Compute the elementwise ratio of the + * two given vectors, that is let + * @p{this[i] = a[i]/b[i]}. This is + * useful for example if you want to + * compute the cellwise ratio of true to + * estimated error. + * + * This vector is appropriately + * scaled to hold the result. + * + * If any of the @p{b[i]} is + * zero, the result is + * undefined. No attempt is made + * to catch such situations. + */ + void ratio (const VectorBase &a, + const VectorBase &b); + + /** + * Print to a + * stream. @p{precision} denotes + * the desired precision with + * which values shall be printed, + * @p{scientific} whether + * scientific notation shall be + * used. If @p{across} is + * @p{true} then the vector is + * printed in a line, while if + * @p{false} then the elements + * are printed on a separate line + * each. + */ + void print (std::ostream &out, + const unsigned int precision = 3, + const bool scientific = true, + const bool across = true) const; + + /** + * Swap the contents of this + * vector and the other vector + * @p{v}. One could do this + * operation with a temporary + * variable and copying over the + * data elements, but this + * function is significantly more + * efficient since it only swaps + * the pointers to the data of + * the two vectors and therefore + * does not need to allocate + * temporary storage and move + * data around. + * + * This function is analog to the + * the @p{swap} function of all C++ + * standard containers. Also, + * there is a global function + * @p{swap(u,v)} that simply calls + * @p{u.swap(v)}, again in analogy + * to standard functions. + */ + void swap (VectorBase &v); + + + /** + * Conversion operator to gain access + * to the underlying PETSc type. If you + * do this, you cut this class off some + * information it may need, so this + * conversion operator should only be + * used if you know what you do. In + * particular, it should only be used + * for read-only operations into the + * vector. + */ + operator const Vec & () const; + + /** + * Exception + */ + DeclException1 (ExcPETScError, + int, + << "An error with error number " << arg1 + << " occured while calling a PETSc function"); + + protected: + /** + * A generic vector object in + * PETSc. The actual type, a sequential + * vector, is set in the constructor. + */ + Vec vector; + + + /** + * PETSc doesn't allow to mix additions + * to matrix entries and overwriting + * them (to make synchronisation of + * parallel computations + * simpler). Since the interface of the + * existing classes don't support the + * notion of not interleaving things, + * we have to emulate this + * ourselves. The way we do it is to, + * for each access operation, store + * whether it is an insertion or an + * addition. If the previous one was of + * different type, then we first have + * to flush the PETSc buffers; + * otherwise, we can simply go on. + * + * The following structure and variable + * declare and store the previous + * state. + */ + struct LastAction + { + enum Values { none, insert, add }; + }; + + + /** + * Store whether the last action was a + * write or add operation. This + * variable is @p{mutable} so that the + * accessor classes can write to it, + * even though the vector object they + * refer to is constant. + */ + mutable LastAction::Values last_action; + + /** + * Create a vector of length + * @p{n}. Derived classes have to + * overload this function according to + * the type of vector they create + * (e.g. sequential or + * parallel/distributed vectors). + */ + virtual void create_vector (const unsigned int n) = 0; + + friend class internal::VectorReference; + }; + + + +// ------------------- inline and template functions -------------- + +/** + * Global function @p{swap} which overloads the default implementation + * of the C++ standard library which uses a temporary object. The + * function simply exchanges the data of the two vectors. + * + * @author Wolfgang Bangerth, 2004 + */ + inline + void swap (VectorBase &u, VectorBase &v) + { + u.swap (v); + } + + + namespace internal + { + inline + VectorReference::VectorReference (const VectorBase &vector, + const unsigned int index) + : + vector (vector), + index (index) + {} + + + inline + const VectorReference & + VectorReference::operator = (const PetscScalar &value) const + { + if (vector.last_action != VectorBase::LastAction::insert) + { + int ierr; + ierr = VecAssemblyBegin (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecAssemblyEnd (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = index; + + const int ierr + = VecSetValues (vector, 1, &petsc_i, &value, INSERT_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + vector.last_action = VectorBase::LastAction::insert; + + return *this; + } + + + + inline + const VectorReference & + VectorReference::operator += (const PetscScalar &value) const + { + if (vector.last_action != VectorBase::LastAction::add) + { + int ierr; + ierr = VecAssemblyBegin (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecAssemblyEnd (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = index; + + // use the PETSc function to add something + const int ierr + = VecSetValues (vector, 1, &petsc_i, &value, ADD_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + vector.last_action = VectorBase::LastAction::add; + + return *this; + } + + + + inline + const VectorReference & + VectorReference::operator -= (const PetscScalar &value) const + { + if (vector.last_action != VectorBase::LastAction::add) + { + int ierr; + ierr = VecAssemblyBegin (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecAssemblyEnd (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = index; + + // use the PETSc function to add something + const PetscScalar subtractand = -value; + const int ierr + = VecSetValues (vector, 1, &petsc_i, &subtractand, ADD_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + vector.last_action = VectorBase::LastAction::add; + + return *this; + } + + + + inline + const VectorReference & + VectorReference::operator *= (const PetscScalar &value) const + { + if (vector.last_action != VectorBase::LastAction::insert) + { + int ierr; + ierr = VecAssemblyBegin (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecAssemblyEnd (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = index; + + const PetscScalar new_value + = static_cast(*this) * value; + + const int ierr + = VecSetValues (vector, 1, &petsc_i, &new_value, INSERT_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + vector.last_action = VectorBase::LastAction::insert; + + return *this; + } + + + + inline + const VectorReference & + VectorReference::operator /= (const PetscScalar &value) const + { + if (vector.last_action != VectorBase::LastAction::insert) + { + int ierr; + ierr = VecAssemblyBegin (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecAssemblyEnd (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = index; + + const PetscScalar new_value + = static_cast(*this) / value; + + const int ierr + = VecSetValues (vector, 1, &petsc_i, &new_value, INSERT_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + vector.last_action = VectorBase::LastAction::insert; + + return *this; + } + + + + inline + VectorReference::operator PetscScalar () const + { + // this is clumsy: there is no simple + // way in PETSc read an element from a + // vector, i.e. there is no function + // VecGetValue or so. The only way is + // to obtain a pointer to a contiguous + // representation of the vector and + // read from it. Subsequently, the + // vector representation has to be + // restored. If the vector has some + // kind of non-standard format, such as + // for parallel vectors, then this is a + // costly operation, just for a single + // read access.. + PetscScalar *ptr; + int ierr + = VecGetArray (vector, &ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + const PetscScalar value = *(ptr+index); + + ierr = VecRestoreArray (vector, &ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return value; + } + } + + + inline + internal::VectorReference + VectorBase::operator () (const unsigned int index) + { + return internal::VectorReference (*this, index); + } + + + + inline + PetscScalar + VectorBase::operator () (const unsigned int index) const + { + return static_cast(internal::VectorReference (*this, index)); + } + + + + template + VectorBase & + VectorBase::operator = (const ::Vector &v) + { + reinit (v.size()); + // the following isn't necessarily fast, + // but this is due to the fact that PETSc + // doesn't offer an inlined access + // operator. + // + // if someone wants to contribute some + // code: to make this code faster, one + // could either first convert all values + // to PetscScalar, and then set them all + // at once using VecSetValues. This has + // the drawback that it could take quite + // some memory, if the vector is large, + // and it would in addition allocate + // memory on the heap, which is + // expensive. an alternative would be to + // split the vector into chunks of, say, + // 128 elements, convert a chunk at a + // time and set it in the output vector + // using VecSetValues. since 128 elements + // is small enough, this could easily be + // allocated on the stack (as a local + // variable) which would make the whole + // thing much more efficient. + // + // a second way to make things faster is + // for the special case that + // number==PetscScalar. we could then + // declare a specialization of this + // template, and omit the conversion. the + // problem with this is that the best we + // can do is to use VecSetValues, but + // this isn't very efficient either: it + // wants to see an array of indices, + // which in this case a) again takes up a + // whole lot of memory on the heap, and + // b) is totally dumb since its content + // would simply be the sequence + // 0,1,2,3,...,n. the best of all worlds + // would probably be a function in Petsc + // that would take a pointer to an array + // of PetscScalar values and simply copy + // n elements verbatim into the vector... + for (unsigned int i=0; i */ template void vmult (VECTOR&, const VECTOR&) const; - /** + + /** * Apply transpose * preconditioner. Since this is * a symmetric preconditioner, @@ -417,9 +418,9 @@ class PreconditionPSOR : public PreconditionRelaxation * smaller than 2 for numerical * reasons. It defaults to 1. */ - void initialize (const MATRIX& A, - const std::vector& permutation, - const std::vector& inverse_permutation, + void initialize (const MATRIX &A, + const std::vector &permutation, + const std::vector &inverse_permutation, typename PreconditionRelaxation::AdditionalData parameters = typename PreconditionRelaxation::AdditionalData()); @@ -565,40 +566,40 @@ class PreconditionedMatrix : public Subscriptor * pool to obtain the auxiliary * vector. */ - PreconditionedMatrix (const MATRIX& A, - const PRECOND& P, - VectorMemory& mem); + PreconditionedMatrix (const MATRIX & A, + const PRECOND & P, + VectorMemory & mem); /** * Preconditioned * matrix-vector-product. */ - void vmult (VECTOR& dst, const VECTOR& src) const; + void vmult (VECTOR &dst, const VECTOR &src) const; /** * Transposed preconditioned * matrix-vector-product. */ - void Tvmult (VECTOR& dst, const VECTOR& src) const; + void Tvmult (VECTOR &dst, const VECTOR &src) const; /** * Residual $b-PAx$. */ - double residual (VECTOR& dst, const VECTOR& src, const VECTOR& rhs) const; + double residual (VECTOR &dst, const VECTOR &src, const VECTOR &rhs) const; private: /** * Storage for the matrix. */ - const MATRIX& A; + const MATRIX &A; /** * Storage for preconditioner. */ - const PRECOND& P; + const PRECOND &P; /** * Memory pool for vectors. */ - VectorMemory& mem; + VectorMemory &mem; }; @@ -608,7 +609,7 @@ class PreconditionedMatrix : public Subscriptor template inline void -PreconditionIdentity::vmult (VECTOR& dst, const VECTOR& src) const +PreconditionIdentity::vmult (VECTOR &dst, const VECTOR &src) const { dst = src; } @@ -617,14 +618,14 @@ PreconditionIdentity::vmult (VECTOR& dst, const VECTOR& src) const template inline void -PreconditionIdentity::Tvmult (VECTOR& dst, const VECTOR& src) const +PreconditionIdentity::Tvmult (VECTOR &dst, const VECTOR &src) const { dst = src; } template inline void -PreconditionIdentity::vmult_add (VECTOR& dst, const VECTOR& src) const +PreconditionIdentity::vmult_add (VECTOR &dst, const VECTOR &src) const { dst.add(src); } @@ -633,7 +634,7 @@ PreconditionIdentity::vmult_add (VECTOR& dst, const VECTOR& src) const template inline void -PreconditionIdentity::Tvmult_add (VECTOR& dst, const VECTOR& src) const +PreconditionIdentity::Tvmult_add (VECTOR &dst, const VECTOR &src) const { dst.add(src); } @@ -654,7 +655,7 @@ PreconditionRelaxation::initialize (const MATRIX &rA, template template inline void -PreconditionJacobi::vmult (VECTOR& dst, const VECTOR& src) const +PreconditionJacobi::vmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_Jacobi (dst, src, this->relaxation); @@ -665,7 +666,7 @@ PreconditionJacobi::vmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionJacobi::Tvmult (VECTOR& dst, const VECTOR& src) const +PreconditionJacobi::Tvmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_Jacobi (dst, src, this->relaxation); @@ -677,7 +678,7 @@ PreconditionJacobi::Tvmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionSOR::vmult (VECTOR& dst, const VECTOR& src) const +PreconditionSOR::vmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_SOR (dst, src, this->relaxation); @@ -688,7 +689,7 @@ PreconditionSOR::vmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionSOR::Tvmult (VECTOR& dst, const VECTOR& src) const +PreconditionSOR::Tvmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_TSOR (dst, src, this->relaxation); @@ -700,7 +701,7 @@ PreconditionSOR::Tvmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionSSOR::vmult (VECTOR& dst, const VECTOR& src) const +PreconditionSSOR::vmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_SSOR (dst, src, this->relaxation); @@ -711,7 +712,7 @@ PreconditionSSOR::vmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionSSOR::Tvmult (VECTOR& dst, const VECTOR& src) const +PreconditionSSOR::Tvmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); this->A->precondition_SSOR (dst, src, this->relaxation); @@ -724,8 +725,8 @@ template inline void PreconditionPSOR::initialize ( const MATRIX &rA, - const std::vector& p, - const std::vector& ip, + const std::vector &p, + const std::vector &ip, typename PreconditionRelaxation::AdditionalData parameters) { permutation = &p; @@ -737,7 +738,7 @@ PreconditionPSOR::initialize ( template template inline void -PreconditionPSOR::vmult (VECTOR& dst, const VECTOR& src) const +PreconditionPSOR::vmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); dst = src; @@ -749,7 +750,7 @@ PreconditionPSOR::vmult (VECTOR& dst, const VECTOR& src) const template template inline void -PreconditionPSOR::Tvmult (VECTOR& dst, const VECTOR& src) const +PreconditionPSOR::Tvmult (VECTOR &dst, const VECTOR &src) const { Assert (this->A!=0, ExcNotInitialized()); dst = src; @@ -771,8 +772,8 @@ PreconditionUseMatrix::PreconditionUseMatrix(const MATRIX & template void -PreconditionUseMatrix::vmult (VECTOR& dst, - const VECTOR& src) const +PreconditionUseMatrix::vmult (VECTOR &dst, + const VECTOR &src) const { (matrix.*precondition)(dst, src); } @@ -802,9 +803,9 @@ PreconditionLACSolver template void PreconditionLACSolver -::initialize (SOLVER& s, - const MATRIX& m, - const PRECONDITION& p) +::initialize (SOLVER &s, + const MATRIX &m, + const PRECONDITION &p) { solver = &s; matrix = &m; @@ -815,8 +816,8 @@ PreconditionLACSolver template template void -PreconditionLACSolver::vmult (VECTOR& dst, - const VECTOR& src) const +PreconditionLACSolver::vmult (VECTOR &dst, + const VECTOR &src) const { Assert (solver !=0 && matrix != 0 && precondition != 0, ExcNotInitialized()); @@ -830,9 +831,9 @@ PreconditionLACSolver::vmult (VECTOR& dst, template inline PreconditionedMatrix -::PreconditionedMatrix (const MATRIX& A, - const PRECOND& P, - VectorMemory& mem): +::PreconditionedMatrix (const MATRIX & A, + const PRECOND &P, + VectorMemory & mem): A(A), P(P), mem(mem) {} @@ -840,8 +841,8 @@ PreconditionedMatrix template inline void PreconditionedMatrix -::vmult (VECTOR& dst, - const VECTOR& src) const +::vmult (VECTOR &dst, + const VECTOR &src) const { VECTOR* h = mem.alloc(); h->reinit(src); @@ -855,8 +856,8 @@ PreconditionedMatrix template inline void PreconditionedMatrix -::Tvmult (VECTOR& dst, - const VECTOR& src) const +::Tvmult (VECTOR &dst, + const VECTOR &src) const { VECTOR* h = mem.alloc(); h->reinit(src); @@ -870,9 +871,9 @@ PreconditionedMatrix template inline double PreconditionedMatrix -::residual (VECTOR& dst, - const VECTOR& src, - const VECTOR& rhs) const +::residual (VECTOR &dst, + const VECTOR &src, + const VECTOR &rhs) const { VECTOR* h = mem.alloc(); h->reinit(src); diff --git a/deal.II/lac/include/lac/solver.h b/deal.II/lac/include/lac/solver.h index 71fdba9b18..b2aeeceafa 100644 --- a/deal.II/lac/include/lac/solver.h +++ b/deal.II/lac/include/lac/solver.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -91,7 +91,7 @@ class SolverControl; * * // scale the elements of the vector * // by a fixed value - * void scale (const double a); + * VECTOR & operator *= (const double a); * * // return the l2 norm of the vector * double l2_norm () const; @@ -108,13 +108,14 @@ class SolverControl; * * @sect3{AdditionalData} * - * Several solvers need additional data, like the damping parameter @p{omega} of the - * @p{SolverRichardson} class or the maximum number of temporary vectors of the @p{SolverGMRES}. - * To have a standardized constructor for each solver class the @p{struct AdditionalData} - * has been introduced to each solver class. Some solvers need no additional data, like - * @p{SolverCG} or @p{SolverBicgstab}. For these solvers the struct @p{AdditionalData} is empty - * and calling the constructor may be done without giving the additional structure as - * an argument as a default @p{AdditionalData} is set by default. + * Several solvers need additional data, like the damping parameter @p{omega} + * of the @p{SolverRichardson} class or the maximum number of temporary + * vectors of the @p{SolverGMRES}. To have a standardized constructor for + * each solver class the @p{struct AdditionalData} has been introduced to each + * solver class. Some solvers need no additional data, like @p{SolverCG} or + * @p{SolverBicgstab}. For these solvers the struct @p{AdditionalData} is + * empty and calling the constructor may be done without giving the additional + * structure as an argument as a default @p{AdditionalData} is set by default. * * Now the generating of a solver looks like * @begin{verbatim} @@ -130,11 +131,12 @@ class SolverControl; * SolverCG solver_cg (solver_control, vector_memory); * @end{verbatim} * - * Using a unified constructor parameter list for all solvers was introduced when the - * @p{SolverSelector} class was written; the unified interface enabled us to use this - * class unchanged even if the number of types of parameters to a certain solver - * changes and it is still possible in a simple way to give these additional data to - * the @p{SolverSelector} object for each solver which it may use. + * Using a unified constructor parameter list for all solvers was introduced + * when the @p{SolverSelector} class was written; the unified interface + * enabled us to use this class unchanged even if the number of types of + * parameters to a certain solver changes and it is still possible in a simple + * way to give these additional data to the @p{SolverSelector} object for each + * solver which it may use. * * @author Wolfgang Bangerth, Guido Kanschat, Ralf Hartmann, 1997-2001 */ @@ -155,12 +157,14 @@ class Solver : public Subscriptor * least as long as that of the solver * object. */ - Solver (SolverControl &, VectorMemory &); + Solver (SolverControl &, + VectorMemory &); /** - * Access to control object. + * Access to object that controls + * convergence. */ - SolverControl& control() const; + SolverControl & control() const; protected: diff --git a/deal.II/lac/include/lac/solver_cg.h b/deal.II/lac/include/lac/solver_cg.h index 142a67d777..d691f9a4f8 100644 --- a/deal.II/lac/include/lac/solver_cg.h +++ b/deal.II/lac/include/lac/solver_cg.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -71,35 +71,32 @@ class SolverCG : public Solver { public: /** - * Standardized data struct to - * pipe additional data to the - * solver. + * Standardized data struct to pipe + * additional data to the solver. */ struct AdditionalData { - /** - * Write coefficients alpha and - * beta to the log file for - later use in eigenvalue estimates. - */ - bool log_coefficients; - - /** - * Constructor. Initialize data fields. - * Confer the description of those. - */ - AdditionalData (bool log_coefficients = false) - : - log_coefficients (log_coefficients) - {} + /** + * Write coefficients alpha and beta + * to the log file for later use in + * eigenvalue estimates. + */ + bool log_coefficients; + + /** + * Constructor. Initialize data + * fields. Confer the description of + * those. + */ + AdditionalData (const bool log_coefficients = false); }; /** * Constructor. */ - SolverCG (SolverControl &cn, + SolverCG (SolverControl &cn, VectorMemory &mem, - const AdditionalData &data=AdditionalData()); + const AdditionalData &data = AdditionalData()); /** * Virtual destructor. @@ -110,7 +107,7 @@ class SolverCG : public Solver * Solve the linear system $Ax=b$ * for x. */ - template + template void solve (const MATRIX &A, VECTOR &x, @@ -177,24 +174,34 @@ class SolverCG : public Solver /*------------------------- Implementation ----------------------------*/ -template -SolverCG::SolverCG(SolverControl &cn, + +template +inline +SolverCG::AdditionalData:: +AdditionalData (const bool log_coefficients) + : + log_coefficients (log_coefficients) +{} + + +template +SolverCG::SolverCG(SolverControl &cn, VectorMemory &mem, const AdditionalData &data) : - Solver(cn,mem), - additional_data(data) + Solver(cn,mem), + additional_data(data) {} -template +template SolverCG::~SolverCG () {} -template +template double SolverCG::criterion() { @@ -203,7 +210,7 @@ SolverCG::criterion() -template +template void SolverCG::cleanup() { @@ -216,7 +223,7 @@ SolverCG::cleanup() -template +template void SolverCG::print_vectors(const unsigned int, const VECTOR&, @@ -226,8 +233,8 @@ SolverCG::print_vectors(const unsigned int, -template -template +template +template void SolverCG::solve (const MATRIX &A, VECTOR &x, @@ -281,7 +288,7 @@ SolverCG::solve (const MATRIX &A, return; } - g.scale(-1.); + g *= -1.; precondition.vmult(h,g); d.equ(-1.,h); diff --git a/deal.II/lac/include/lac/solver_control.h b/deal.II/lac/include/lac/solver_control.h index 1f70b3fc09..7848cf3505 100644 --- a/deal.II/lac/include/lac/solver_control.h +++ b/deal.II/lac/include/lac/solver_control.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -325,7 +325,6 @@ class SolverControl : public Subscriptor * @p{set_failure_criterion} */ double relative_failure_residual; - /** * @p{failure_residual} equals the diff --git a/deal.II/lac/include/lac/solver_gmres.h b/deal.II/lac/include/lac/solver_gmres.h index c64b3361b4..a873f58359 100644 --- a/deal.II/lac/include/lac/solver_gmres.h +++ b/deal.II/lac/include/lac/solver_gmres.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -153,23 +153,21 @@ namespace internal * that these will continue to work even if number or type of the * additional parameters for a certain solver changes. * - * For the GMRes method, the @p{AdditionalData} structure contains the - * number of temporary vectors as commented upon above. By default, - * the number of these vectors is set to 30. The @p{AdditionalData} - * also containes a flag indicating the use of right or left - * preconditioning. The default is left preconditioning. Finally it - * includes a flag indicating whether or not the default residual is - * used as stopping criterion. By default, the left preconditioned - * GMRes uses the preconditioned residual and the right preconditioned - * GMRes uses the normal, i.e. unpreconditioned, residual as stopping - * criterion. If the @p{use_default_residual} flag is @p{false}, the - * left preconditioned GMRes uses as stopping criterion the - * unpreconditioned residual and the right preconditioned GMRes the - * preconditioned residual. But be aware that the non-default - * residuals are not automatically computed by the GMRes method but - * need to be computed in addition. This (especially for the left - * preconditioned GMRes) might lead to a significant loss in the - * solver performance. Therefore, the user should set + * For the GMRes method, the @p{AdditionalData} structure contains the number + * of temporary vectors as commented upon above. By default, the number of + * these vectors is set to 30. The @p{AdditionalData} also containes a flag + * indicating the use of right or left preconditioning. The default is left + * preconditioning. Finally it includes a flag indicating whether or not the + * default residual is used as stopping criterion. By default, the left + * preconditioned GMRes uses the preconditioned residual and the right + * preconditioned GMRes uses the normal, i.e. unpreconditioned, residual as + * stopping criterion. If the @p{use_default_residual} flag is @p{false}, the + * left preconditioned GMRes uses as stopping criterion the unpreconditioned + * residual and the right preconditioned GMRes the preconditioned + * residual. But be aware that the non-default residuals are not automatically + * computed by the GMRes method but need to be computed in addition. This + * (especially for the left preconditioned GMRes) might lead to a significant + * loss in the solver performance. Therefore, the user should set * @p{use_default_residual=false} only for debugging/testing purposes. * * For the requirements on matrices and vectors in order to work with @@ -189,23 +187,18 @@ class SolverGMRES : public Solver struct AdditionalData { /** - * Constructor. By default, - * set the number of - * temporary vectors to 30, - * preconditioning from left - * and the residual of the - * stopping criterion to the - * default residual + * Constructor. By default, set the + * number of temporary vectors to 30, + * i.e. do a restart every + * approximately 30 iterations. Also + * set preconditioning from left and + * the residual of the stopping + * criterion to the default residual * (cf. class documentation). */ - AdditionalData(const unsigned int max_n_tmp_vectors = 30, - bool right_preconditioning = false, - bool use_default_residual = true) - : - max_n_tmp_vectors(max_n_tmp_vectors), - right_preconditioning(right_preconditioning), - use_default_residual(use_default_residual) - {}; + AdditionalData (const unsigned int max_n_tmp_vectors = 30, + const bool right_preconditioning = false, + const bool use_default_residual = true); /** * Maximum number of @@ -435,6 +428,19 @@ namespace internal } + +template +inline +SolverGMRES::AdditionalData:: +AdditionalData (const unsigned int max_n_tmp_vectors, + const bool right_preconditioning, + const bool use_default_residual) + : + max_n_tmp_vectors(max_n_tmp_vectors), + right_preconditioning(right_preconditioning), + use_default_residual(use_default_residual) +{} + template SolverGMRES::SolverGMRES (SolverControl &cn, VectorMemory &mem, @@ -620,7 +626,7 @@ SolverGMRES::solve (const MATRIX &A, gamma(0) = rho; - v.scale (1./rho); + v *= 1./rho; // inner iteration doing at // most as many steps as there @@ -671,7 +677,7 @@ SolverGMRES::solve (const MATRIX &A, s = vv.l2_norm(); h(inner_iteration+1) = s; - vv.scale(1./s); + vv *= 1./s; /* Transformation into triagonal structure */ diff --git a/deal.II/lac/include/lac/solver_minres.h b/deal.II/lac/include/lac/solver_minres.h index c590b7b4eb..32c41d0ad7 100644 --- a/deal.II/lac/include/lac/solver_minres.h +++ b/deal.II/lac/include/lac/solver_minres.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -202,19 +202,19 @@ SolverMinRes::solve (const MATRIX &A, Vm1 = this->memory.alloc(); Vm2 = this->memory.alloc(); // define some aliases for simpler access - typedef VECTOR vecref; - vecref u[3] = {*Vu0, *Vu1, *Vu2}; - vecref m[3] = {*Vm0, *Vm1, *Vm2}; - vecref v = *Vv; + typedef VECTOR *vecptr; + vecptr u[3] = {Vu0, Vu1, Vu2}; + vecptr m[3] = {Vm0, Vm1, Vm2}; + VECTOR &v = *Vv; // resize the vectors, but do not set // the values since they'd be overwritten // soon anyway. - u[0].reinit(VS,true); - u[1].reinit(VS,true); - u[2].reinit(VS,true); - m[0].reinit(VS,true); - m[1].reinit(VS,true); - m[2].reinit(VS,true); + u[0]->reinit(VS,true); + u[1]->reinit(VS,true); + u[2]->reinit(VS,true); + m[0]->reinit(VS,true); + m[1]->reinit(VS,true); + m[2]->reinit(VS,true); v.reinit(VS,true); // some values needed @@ -236,17 +236,17 @@ SolverMinRes::solve (const MATRIX &A, // Start of the solution process - A.vmult(m[0],x); - u[1] = b; - u[1] -= m[0]; + A.vmult(*m[0],x); + *u[1] = b; + *u[1] -= *m[0]; // Precondition is applied. // The preconditioner has to be // positiv definite and symmetric // M v = u[1] - precondition.vmult (v,u[1]); + precondition.vmult (v,*u[1]); - delta[1] = v * u[1]; + delta[1] = v * (*u[1]); // Preconditioner positive Assert (delta[1]>=0, ExcPreconditionerNotDefinite()); @@ -254,34 +254,34 @@ SolverMinRes::solve (const MATRIX &A, r_l2 = r0; - u[0].reinit(VS); + u[0]->reinit(VS); delta[0] = 1.; - m[0].reinit(VS); - m[1].reinit(VS); - m[2].reinit(VS); + m[0]->reinit(VS); + m[1]->reinit(VS); + m[2]->reinit(VS); conv = this->control().check(0,r_l2); while (conv==SolverControl::iterate) { if (delta[1]!=0) - v.scale(1./sqrt(delta[1])); + v *= 1./sqrt(delta[1]); else v.reinit(VS); - A.vmult(u[2],v); - u[2].add (-sqrt(delta[1]/delta[0]), u[0]); + A.vmult(*u[2],v); + u[2]->add (-sqrt(delta[1]/delta[0]), *u[0]); - gamma = u[2] * v; - u[2].add (-gamma / sqrt(delta[1]), u[1]); - m[0] = v; + gamma = *u[2] * v; + u[2]->add (-gamma / sqrt(delta[1]), *u[1]); + *m[0] = v; // precondition: solve M v = u[2] // Preconditioner has to be positiv // definite and symmetric. - precondition.vmult(v,u[2]); + precondition.vmult(v,*u[2]); - delta[2] = v * u[2]; + delta[2] = v * (*u[2]); Assert (delta[2]>=0, ExcPreconditionerNotDefinite()); @@ -309,11 +309,11 @@ SolverMinRes::solve (const MATRIX &A, if (j==1) tau = r0 * c; - m[0].add (-e[0], m[1]); + m[0]->add (-e[0], *m[1]); if (j>1) - m[0].add (-f[0],m[2]); - m[0].scale(1./d); - x.add (tau, m[0]); + m[0]->add (-f[0], *m[2]); + *m[0] *= 1./d; + x.add (tau, *m[0]); r_l2 *= fabs(s); conv = this->control().check(j,r_l2); @@ -330,14 +330,14 @@ SolverMinRes::solve (const MATRIX &A, // but it can be made more efficient, // since the value of m[0] is no more // needed in the next iteration - swap (m[2], m[1]); - swap (m[1], m[0]); + swap (*m[2], *m[1]); + swap (*m[1], *m[0]); // likewise, but reverse direction: // u[0] = u[1]; // u[1] = u[2]; - swap (u[0], u[1]); - swap (u[1], u[2]); + swap (*u[0], *u[1]); + swap (*u[1], *u[2]); // these are scalars, so need // to bother diff --git a/deal.II/lac/include/lac/solver_richardson.h b/deal.II/lac/include/lac/solver_richardson.h index d2fc5e732f..a136c3c16c 100644 --- a/deal.II/lac/include/lac/solver_richardson.h +++ b/deal.II/lac/include/lac/solver_richardson.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -62,16 +62,14 @@ class SolverRichardson : public Solver * set the damping parameter * to one. */ - AdditionalData(double omega=1, - bool use_preconditioned_residual = false): - omega(omega), - use_preconditioned_residual(use_preconditioned_residual) - {}; + AdditionalData (const double omega = 1, + const bool use_preconditioned_residual = false); /** * Relaxation parameter. */ double omega; + /** * Parameter for stopping criterion. */ @@ -82,7 +80,7 @@ class SolverRichardson : public Solver /** * Constructor. */ - SolverRichardson (SolverControl &cn, + SolverRichardson (SolverControl &cn, VectorMemory &mem, const AdditionalData &data=AdditionalData()); @@ -116,7 +114,7 @@ class SolverRichardson : public Solver * Set the damping-coefficient. * Default is 1., i.e. no damping. */ - void set_omega(double om=1.); + void set_omega (const double om=1.); /** * Interface for derived class. @@ -170,7 +168,18 @@ class SolverRichardson : public Solver /*----------------- Implementation of the Richardson Method ------------------*/ -template + +template +inline +SolverRichardson::AdditionalData:: +AdditionalData (const double omega, + const bool use_preconditioned_residual) + : + omega(omega), + use_preconditioned_residual(use_preconditioned_residual) +{} + +template SolverRichardson::SolverRichardson(SolverControl &cn, VectorMemory &mem, const AdditionalData &data): @@ -180,13 +189,13 @@ SolverRichardson::SolverRichardson(SolverControl &cn, -template +template SolverRichardson::~SolverRichardson() {} -template -template +template +template void SolverRichardson::solve (const MATRIX &A, VECTOR &x, @@ -252,8 +261,8 @@ SolverRichardson::solve (const MATRIX &A, } -template -template +template +template void SolverRichardson::Tsolve (const MATRIX &A, VECTOR &x, @@ -309,7 +318,7 @@ SolverRichardson::Tsolve (const MATRIX &A, } -template +template void SolverRichardson::print_vectors(const unsigned int, const VECTOR&, @@ -319,7 +328,7 @@ SolverRichardson::print_vectors(const unsigned int, -template +template inline typename VECTOR::value_type SolverRichardson::criterion() { @@ -327,9 +336,9 @@ SolverRichardson::criterion() } -template +template inline void -SolverRichardson::set_omega(double om) +SolverRichardson::set_omega (const double om) { additional_data.omega=om; } diff --git a/deal.II/lac/include/lac/sparse_matrix.h b/deal.II/lac/include/lac/sparse_matrix.h index c04c023490..e77c1f5c95 100644 --- a/deal.II/lac/include/lac/sparse_matrix.h +++ b/deal.II/lac/include/lac/sparse_matrix.h @@ -367,7 +367,8 @@ class SparseMatrix : public virtual Subscriptor * store zero values in * non-existent fields. */ - void set (const unsigned int i, const unsigned int j, + void set (const unsigned int i, + const unsigned int j, const number value); /** @@ -390,7 +391,8 @@ class SparseMatrix : public virtual Subscriptor * store zero values in * non-existent fields. */ - void add (const unsigned int i, const unsigned int j, + void add (const unsigned int i, + const unsigned int j, const number value); /** @@ -503,18 +505,20 @@ class SparseMatrix : public virtual Subscriptor /** * Add matrix scaled by - * factor to this - * matrix. The function throws an - * error if the sparsity patterns - * of the two involved matrices - * do not point to the same + * factor to this matrix, + * i.e. the matrix factor*matrix + * is added to this. This + * function throws an error if the + * sparsity patterns of the two involved + * matrices do not point to the same * object, since in this case the * operation is cheaper. * - * The source matrix may be a matrix - * of arbitrary type, as long as its - * data type is convertible to the - * data type of this matrix. + * The source matrix may be a sparse + * matrix over an arbitrary underlying + * scalar type, as long as its data type + * is convertible to the data type of + * this matrix. */ template void add_scaled (const number factor, @@ -538,10 +542,11 @@ class SparseMatrix : public virtual Subscriptor * matrix), use the el() * function. * - * @deprecated Consider using - * const_iterator instead, since - * it is tailored better to a - * sparse matrix structure. + * If you are looping over all elements, + * consider using a + * const_iterator instead, since + * it is tailored better to a sparse + * matrix structure. */ number operator () (const unsigned int i, const unsigned int j) const; @@ -564,10 +569,11 @@ class SparseMatrix : public virtual Subscriptor * solution, since the sparsity * of the matrix is not used. * - * @deprecated Consider using - * const_iterator instead, since - * it is tailored better to a - * sparse matrix structure. + * If you are looping over all elements, + * consider using a + * const_iterator instead, since + * it is tailored better to a sparse + * matrix structure. */ number el (const unsigned int i, const unsigned int j) const; @@ -656,6 +662,9 @@ class SparseMatrix : public virtual Subscriptor * Matrix-vector multiplication: * let dst = M*src with * M being this matrix. + * + * Source and destination must + * not be the same vector. */ template void vmult (Vector &dst, @@ -668,6 +677,9 @@ class SparseMatrix : public virtual Subscriptor * matrix. This function does the * same as vmult() but takes * the transposed matrix. + * + * Source and destination must + * not be the same vector. */ template void Tvmult (Vector &dst, @@ -679,6 +691,9 @@ class SparseMatrix : public virtual Subscriptor * M*src on dst * with M being this * matrix. + * + * Source and destination must + * not be the same vector. */ template void vmult_add (Vector &dst, @@ -693,6 +708,9 @@ class SparseMatrix : public virtual Subscriptor * does the same as vmult_add() * but takes the transposed * matrix. + * + * Source and destination must + * not be the same vector. */ template void Tvmult_add (Vector &dst, @@ -754,6 +772,14 @@ class SparseMatrix : public virtual Subscriptor */ number linfty_norm () const; + /** + * Return the frobenius norm of the + * matrix, i.e. the square root of the + * sum of squares of all entries in the + * matrix. + */ + number frobenius_norm () const; + /** * Compute the residual of an * equation Mx=b, where @@ -764,6 +790,10 @@ class SparseMatrix : public virtual Subscriptor * l2 norm of * the residual vector is * returned. + * + * Source x and destination + * dst must not be the same + * vector. */ template somenumber residual (Vector &dst, @@ -1123,6 +1153,10 @@ class SparseMatrix : public virtual Subscriptor int, int, << "The iterators denote a range of " << arg1 << " elements, but the given number of rows was " << arg2); + /** + * Exception + */ + DeclException0 (ExcSourceEqualsDestination); private: /** @@ -1348,8 +1382,8 @@ number SparseMatrix::operator () (const unsigned int i, const unsigned int j) const { Assert (cols != 0, ExcMatrixNotInitialized()); - Assert (cols->operator()(i,j) != SparsityPattern::invalid_entry, - ExcInvalidIndex(i,j)); + AssertThrow (cols->operator()(i,j) != SparsityPattern::invalid_entry, + ExcInvalidIndex(i,j)); return val[cols->operator()(i,j)]; } diff --git a/deal.II/lac/include/lac/sparse_matrix.templates.h b/deal.II/lac/include/lac/sparse_matrix.templates.h index dafd336610..a7d25e4326 100644 --- a/deal.II/lac/include/lac/sparse_matrix.templates.h +++ b/deal.II/lac/include/lac/sparse_matrix.templates.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -286,6 +286,8 @@ SparseMatrix::vmult (Vector& dst, Assert (val != 0, ExcMatrixNotInitialized()); Assert(m() == dst.size(), ExcDimensionMismatch(m(),dst.size())); Assert(n() == src.size(), ExcDimensionMismatch(n(),src.size())); + + Assert (&src != &dst, ExcSourceEqualsDestination()); const unsigned int n_rows = m(); @@ -384,6 +386,8 @@ SparseMatrix::Tvmult (Vector& dst, Assert(n() == dst.size(), ExcDimensionMismatch(n(),dst.size())); Assert(m() == src.size(), ExcDimensionMismatch(m(),src.size())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + dst.clear (); for (unsigned int i=0;i::vmult_add (Vector& dst, Assert(m() == dst.size(), ExcDimensionMismatch(m(),dst.size())); Assert(n() == src.size(), ExcDimensionMismatch(n(),src.size())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + const unsigned int n_rows = m(); const number *val_ptr = &val[cols->rowstart[0]]; const unsigned int *colnum_ptr = &cols->colnums[cols->rowstart[0]]; @@ -434,14 +440,14 @@ SparseMatrix::Tvmult_add (Vector& dst, Assert(n() == dst.size(), ExcDimensionMismatch(n(),dst.size())); Assert(m() == src.size(), ExcDimensionMismatch(m(),src.size())); + Assert (&src != &dst, ExcSourceEqualsDestination()); + for (unsigned int i=0;irowstart[i]; jrowstart[i+1] ;j++) - { - const unsigned int p = cols->colnums[j]; - dst(p) += val[j] * src(i); - } - } + for (unsigned int j=cols->rowstart[i]; jrowstart[i+1] ;j++) + { + const unsigned int p = cols->colnums[j]; + dst(p) += val[j] * src(i); + } } @@ -688,6 +694,7 @@ number SparseMatrix::l1_norm () const } + template number SparseMatrix::linfty_norm () const { @@ -711,6 +718,24 @@ number SparseMatrix::linfty_norm () const } + +template +number SparseMatrix::frobenius_norm () const +{ + // simply add up all entries in the + // sparsity pattern, without taking any + // reference to rows or columns + number norm_sqr = 0; + const unsigned int n_rows = m(); + for (const number *ptr = &val[0]; + ptr != &val[cols->rowstart[n_rows]]; ++ptr) + norm_sqr += *ptr * *ptr; + + return std::sqrt (norm_sqr); +} + + + template template somenumber @@ -724,6 +749,8 @@ SparseMatrix::residual (Vector &dst, Assert(m() == b.size(), ExcDimensionMismatch(m(),b.size())); Assert(n() == u.size(), ExcDimensionMismatch(n(),u.size())); + Assert (&u != &dst, ExcSourceEqualsDestination()); + const unsigned int n_rows = m(); // if in MT mode and size sufficiently diff --git a/deal.II/lac/include/lac/sparsity_pattern.h b/deal.II/lac/include/lac/sparsity_pattern.h index 4f41ba1d91..b8ad6e0755 100644 --- a/deal.II/lac/include/lac/sparsity_pattern.h +++ b/deal.II/lac/include/lac/sparsity_pattern.h @@ -358,12 +358,13 @@ class SparsityPattern : public Subscriptor * This function compresses the sparsity * structure that this object represents. * It does so by eliminating unused - * entries and sorting the remaining - * ones to allow faster access by usage - * of binary search algorithms. A special - * sorting scheme is used for the diagonal - * entry of quadratic matrices, which is - * always the first entry of each row. + * entries and sorting the remaining ones + * to allow faster access by usage of + * binary search algorithms. A special + * sorting scheme is used for the + * diagonal entry of quadratic matrices, + * which is always the first entry of + * each row. * * The memory which is no more * needed is released. diff --git a/deal.II/lac/include/lac/vector.h b/deal.II/lac/include/lac/vector.h index 5d13337d71..4f9eaee96d 100644 --- a/deal.II/lac/include/lac/vector.h +++ b/deal.II/lac/include/lac/vector.h @@ -17,6 +17,10 @@ #include #include +#ifdef DEAL_II_USE_PETSC +# include +#endif + #include /*! @addtogroup Vectors @@ -73,23 +77,24 @@ class Vector */ //@{ /** - * Dummy-Constructor. Dimension=0 + * Constructor. Create a vector of + * dimension zero. */ Vector (); /** - * Copy-Constructor. Dimension set to - * that of V, all components are copied - * from V. + * Copy-constructor. Sets the dimension + * to that of the given vector, and + * copies all elements. * * We would like to make this * constructor explicit, but STL * insists on using it implicitly. */ - Vector (const Vector& V); + Vector (const Vector &v); -// note: I disabled this function for the time being, since egcs1.1.2 +// note: I disabled this function for the time being, since gcc2.95 // does not respect the "explicit" keyword for template constructors. // this leads to unwanted conversions and in some places to automatically // generated temporaries, where this is not a good idea. [WB] @@ -105,11 +110,31 @@ class Vector // template // explicit // Vector (const Vector &v); + +#ifdef DEAL_II_USE_PETSC + /** + * Another copy constructor: copy the + * values from a PETSc wrapper vector + * class. This copy constructor is only + * available if PETSc was detected during + * configuration time. + */ + Vector (const PETScWrappers::VectorBase &v); +#endif /** * Constructor. Set dimension to * @p{n} and initialize all * elements with zero. + * + * The constructor is made explicit to + * avoid accidents like this: + * @p{v=0;}. Presumably, the user wants + * to set every element of the vector to + * zero, but instead, what happens is + * this call: @p{v=Vector(0);}, + * i.e. the vector is replaced by one of + * length zero. */ explicit Vector (const unsigned int n); @@ -121,7 +146,8 @@ class Vector * to the @p{std::vector} class. */ template - Vector (const InputIterator first, const InputIterator last); + Vector (const InputIterator first, + const InputIterator last); /** * Destructor, deallocates @@ -131,31 +157,56 @@ class Vector */ virtual ~Vector (); - /** + /** + * This function does nothing but is + * there for compatibility with the + * @p{PETScWrappers::Vector} class. + * + * For the PETSc vector wrapper class, + * thios function compresses the + * underlying representation of the PETSc + * object, i.e. flushes the buffers of + * the vector object if it has any. This + * function is necessary after writing + * into a vector element-by-element and + * before anything else can be done on + * it. + * + * However, for the implementation of + * this class, it is immaterial and thus + * an empty function. + */ + void compress () const; + + /** * Set all entries to zero. Equivalent to - * @p{v = 0}, but more obvious and faster. - * Note that this function does not change - * the size of the vector, unlike the - * STL's @p{vector<>::clear} function. + * @p{v = 0}, but more obvious and + * faster. Note that this function does + * not change the size of the vector, + * unlike the STL's @p{vector<>::clear} + * function. */ void clear (); /** * Change the dimension of the vector to - * @p{N}. The reserved memory for this vector - * remains unchanged if possible, to make - * things faster, but this may waste some - * memory, so take this in the back of your - * head. - * However, if @p{N==0} all memory is freed, - * i.e. if you want to resize the vector - * and release the memory not needed, you - * have to first call @p{reinit(0)} and then + * @p{N}. The reserved memory for this + * vector remains unchanged if possible, + * to make things faster; this may waste + * some memory, so keep this in mind. + * However, if @p{N==0} all memory is + * freed, i.e. if you want to resize the + * vector and release the memory not + * needed, you have to first call + * @p{reinit(0)} and then * @p{reinit(N)}. This cited behaviour is - * analogous to that of the STL containers. + * analogous to that of the STL + * containers. * - * On @p{fast==false}, the vector is filled by - * zeros. + * On @p{fast==false}, the vector is + * filled by zeros. Otherwise, the + * elements are left an unspecified + * state. */ void reinit (const unsigned int N, const bool fast=false); @@ -165,9 +216,9 @@ class Vector * vector @p{V}. The same applies as for * the other @p{reinit} function. * - * The elements of @p{V} are not copied, i.e. - * this function is the same as calling - * @p{reinit (V.size(), fast)}. + * The elements of @p{V} are not copied, + * i.e. this function is the same as + * calling @p{reinit (V.size(), fast)}. */ template void reinit (const Vector &V, @@ -199,20 +250,45 @@ class Vector void swap (Vector &v); /** - * $U(0-N) = s$: fill all components. + * Set all components of the vector to + * the given number @p{s}. */ Vector & operator= (const Number s); /** - * $U = V$: copy all components. + * Copy the given vector. Resize the + * present vector if necessary. */ - Vector & operator= (const Vector& V); + Vector & operator= (const Vector &c); /** - * $U = V$ for different types. + * Copy the given vector. Resize the + * present vector if necessary. */ - template - Vector & operator= (const Vector& V); + template + Vector & operator= (const Vector &v); + + /** + * Test for equality. This function + * assumes that the present vector and + * the one to compare with have the same + * size already, since comparing vectors + * of different sizes makes not much + * sense anyway. + */ + template + bool operator == (const Vector &v) const; + + /** + * Test for inequality. This function + * assumes that the present vector and + * the one to compare with have the same + * size already, since comparing vectors + * of different sizes makes not much + * sense anyway. + */ + template + bool operator != (const Vector &v) const; /** * Return the scalar product of @@ -267,11 +343,7 @@ class Vector Number linfty_norm () const; /** - * Return dimension of the vector. This - * function was formerly called @p{n()}, but - * was renamed to get the @p{Vector} class - * closer to the C++ standard library's - * @p{vector} container. + * Return dimension of the vector. */ unsigned int size () const; @@ -284,6 +356,16 @@ class Vector * some time. */ bool all_zero () const; + + /** + * Return @p{true} if the vector has no + * negative entries, i.e. all entries are + * zero or positive. This function is + * used, for example, to check whether + * refinement indicators are really all + * positive (or zero). + */ + bool is_non_negative () const; /** * Make the @p{Vector} class a bit like the @@ -319,12 +401,13 @@ class Vector */ //@{ /** - * Access components, returns U(i). + * Access the value of the @p{i}th + * component. */ Number operator() (const unsigned int i) const; /** - * Access components, returns U(i) + * Access the @p{i}th component * as a writeable reference. */ Number& operator() (const unsigned int i); @@ -335,71 +418,81 @@ class Vector * @name 3: Modification of vectors */ //@{ + /** - * Addition operator. - * Fast equivalent to @p{U.add(1, V)}. + * Add the given vector to the present + * one. */ Vector & operator += (const Vector &V); /** - * Subtraction operator. - * Fast equivalent to @p{U.add(-1, V)}. + * Subtract the given vector from the + * present one. */ Vector & operator -= (const Vector &V); /** - * $U(0-DIM)+=s$. - * Addition of @p{s} to all components. Note - * that @p{s} is a scalar and not a vector. + * Addition of @p{s} to all + * components. Note that @p{s} is a + * scalar and not a vector. */ void add (const Number s); /** - * U+=V. * Simple vector addition, equal to the * @p{operator +=}. */ - void add (const Vector& V); + void add (const Vector &V); /** - * U+=a*V. - * Simple addition of a scaled vector. + * Simple addition of a multiple of a + * vector, i.e. @p{*this += a*V}. */ - void add (const Number a, const Vector& V); + void add (const Number a, const Vector &V); /** - * U+=a*V+b*W. - * Multiple addition of scaled vectors. + * Multiple addition of scaled vectors, + * i.e. @p{*this += a*V+b*W}. */ - void add (const Number a, const Vector& V, - const Number b, const Vector& W); + void add (const Number a, const Vector &V, + const Number b, const Vector &W); /** - * U=s*U+V. - * Scaling and simple vector addition. + * Scaling and simple vector addition, + * i.e. + * @p{*this = s*(*this)+V}. */ - void sadd (const Number s, const Vector& V); + void sadd (const Number s, + const Vector &V); /** - * U=s*U+a*V. - * Scaling and simple addition. + * Scaling and simple addition, i.e. + * @p{*this = s*(*this)+a*V}. */ - void sadd (const Number s, const Number a, const Vector& V); + void sadd (const Number s, + const Number a, + const Vector &V); /** - * U=s*U+a*V+b*W. * Scaling and multiple addition. */ - void sadd (const Number s, const Number a, - const Vector& V, const Number b, const Vector& W); + void sadd (const Number s, + const Number a, + const Vector &V, + const Number b, + const Vector &W); /** - * U=s*U+a*V+b*W+c*X. * Scaling and multiple addition. - */ - void sadd (const Number s, const Number a, - const Vector& V, const Number b, const Vector& W, - const Number c, const Vector& X); + * @p{*this = s*(*this)+a*V + b*W + c*X}. + */ + void sadd (const Number s, + const Number a, + const Vector &V, + const Number b, + const Vector &W, + const Number c, + const Vector &X); /** * Scale each element of the @@ -441,14 +534,13 @@ class Vector void scale (const Vector &scaling_factors); /** - * U=a*V. Assignment. + * Assignment @p{*this = a*V}. */ template void equ (const Number a, const Vector& V); /** - * U=a*V+b*W. - * Replacing by sum. + * Assignment @p{*this = a*V + b*W}. */ void equ (const Number a, const Vector& V, const Number b, const Vector& W); @@ -456,10 +548,10 @@ class Vector /** * Compute the elementwise ratio of the * two given vectors, that is let - * @p{this[i] = a[i]/b[i]}. This is useful - * for example if you want to compute - * the cellwise ratio of true to estimated - * error. + * @p{this[i] = a[i]/b[i]}. This is + * useful for example if you want to + * compute the cellwise ratio of true to + * estimated error. * * This vector is appropriately * scaled to hold the result. @@ -778,6 +870,27 @@ Vector & Vector::operator = (const Number s) return *this; } + + +template +template +inline +bool +Vector::operator != (const Vector& v) const +{ + return ! (*this == v); +} + + + +template +inline +void +Vector::compress () const +{} + + + /*! @addtogroup Vectors *@{ */ diff --git a/deal.II/lac/include/lac/vector.templates.h b/deal.II/lac/include/lac/vector.templates.h index 3ee37bacb5..bac515b256 100644 --- a/deal.II/lac/include/lac/vector.templates.h +++ b/deal.II/lac/include/lac/vector.templates.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -72,6 +72,38 @@ Vector::Vector (const Vector& v) // } +#ifdef DEAL_II_USE_PETSC + +template +Vector::Vector (const PETScWrappers::VectorBase &v) + : + dim(v.size()), + maxdim(v.size()), + val(0) +{ + if (dim) + { + val = new Number[maxdim]; + Assert (val != 0, ExcOutOfMemory()); + + // get a representation of the vector + // and copy it + PetscScalar *start_ptr; + int ierr = VecGetArray (v, &start_ptr); + AssertThrow (ierr == 0, PETScWrappers::VectorBase::ExcPETScError(ierr)); + + std::copy (start_ptr, start_ptr+dim, begin()); + + // restore the representation of the + // vector + ierr = VecRestoreArray (v, &start_ptr); + AssertThrow (ierr == 0, PETScWrappers::VectorBase::ExcPETScError(ierr)); + } +} + +#endif + + template template void Vector::reinit (const Vector& v, const bool fast) @@ -93,7 +125,8 @@ Vector::swap (Vector &v) template -bool Vector::all_zero () const +bool +Vector::all_zero () const { Assert (dim!=0, ExcEmptyVector()); @@ -106,6 +139,23 @@ bool Vector::all_zero () const } + +template +bool +Vector::is_non_negative () const +{ + Assert (dim!=0, ExcEmptyVector()); + + const_iterator p = begin(), + e = end(); + while (p!=e) + if (*p++ < 0.0) + return false; + return true; +} + + + template template Number Vector::operator * (const Vector& v) const @@ -203,6 +253,7 @@ Number Vector::mean_value () const } + template Number Vector::l1_norm () const { @@ -554,6 +605,23 @@ Vector::operator = (const Vector& v) +template +template +bool +Vector::operator == (const Vector& v) const +{ + Assert (dim!=0, ExcEmptyVector()); + Assert (dim == v.size(), ExcDimensionMismatch(dim, v.size())); + + for (unsigned int i=0; i void Vector::print (const char* format) const { @@ -573,6 +641,7 @@ void Vector::print (std::ostream &out, const bool across) const { Assert (dim!=0, ExcEmptyVector()); + AssertThrow (out, ExcIO()); out.precision (precision); if (scientific) diff --git a/deal.II/lac/source/full_matrix.double.cc b/deal.II/lac/source/full_matrix.double.cc index fb891a264c..4a316e2261 100644 --- a/deal.II/lac/source/full_matrix.double.cc +++ b/deal.II/lac/source/full_matrix.double.cc @@ -29,6 +29,7 @@ template void FullMatrix::fill ( template void FullMatrix::add (const TYPEMAT, const FullMatrix&); template void FullMatrix::add ( const FullMatrix&, double, unsigned, unsigned, unsigned, unsigned); +template void FullMatrix::add_scaled (const TYPEMAT, const FullMatrix&); template void FullMatrix::Tadd (const TYPEMAT, const FullMatrix&); template void FullMatrix::Tadd ( const FullMatrix&, double, unsigned, unsigned, unsigned, unsigned); diff --git a/deal.II/lac/source/full_matrix.float.cc b/deal.II/lac/source/full_matrix.float.cc index 5a303d3ecd..58557f413e 100644 --- a/deal.II/lac/source/full_matrix.float.cc +++ b/deal.II/lac/source/full_matrix.float.cc @@ -29,6 +29,7 @@ template void FullMatrix::fill ( template void FullMatrix::add (const TYPEMAT, const FullMatrix&); template void FullMatrix::add ( const FullMatrix&, double, unsigned, unsigned, unsigned, unsigned); +template void FullMatrix::add_scaled (const TYPEMAT, const FullMatrix&); template void FullMatrix::Tadd (const TYPEMAT, const FullMatrix&); template void FullMatrix::Tadd ( const FullMatrix&, double, unsigned, unsigned, unsigned, unsigned); diff --git a/deal.II/lac/source/petsc_full_matrix.cc b/deal.II/lac/source/petsc_full_matrix.cc new file mode 100644 index 0000000000..0f455d6b3a --- /dev/null +++ b/deal.II/lac/source/petsc_full_matrix.cc @@ -0,0 +1,35 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + FullMatrix::FullMatrix (const unsigned int m, + const unsigned int n) + { + const int ierr + = MatCreateSeqDense(PETSC_COMM_SELF, m, n, PETSC_NULL, + &matrix); + + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } +} + + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_matrix_base.cc b/deal.II/lac/source/petsc_matrix_base.cc new file mode 100644 index 0000000000..819c7a7e6a --- /dev/null +++ b/deal.II/lac/source/petsc_matrix_base.cc @@ -0,0 +1,333 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + MatrixBase::MatrixBase () + : + last_action (LastAction::none) + {} + + + + MatrixBase::~MatrixBase () + { + const int ierr = MatDestroy (matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + MatrixBase::reinit () + { + const int ierr = MatZeroEntries (matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + MatrixBase::set (const unsigned int i, + const unsigned int j, + const PetscScalar value) + { + if (last_action != LastAction::insert) + { + int ierr; + ierr = MatAssemblyBegin(matrix,MAT_FLUSH_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = MatAssemblyEnd(matrix,MAT_FLUSH_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = i; + const signed int petsc_j = j; + + const int ierr + = MatSetValues (matrix, 1, &petsc_i, 1, &petsc_j, + &value, INSERT_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + last_action = LastAction::insert; + } + + + + void + MatrixBase::add (const unsigned int i, + const unsigned int j, + const PetscScalar value) + { + if (last_action != LastAction::add) + { + int ierr; + ierr = MatAssemblyBegin(matrix,MAT_FLUSH_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = MatAssemblyEnd(matrix,MAT_FLUSH_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + const signed int petsc_i = i; + const signed int petsc_j = j; + + const int ierr + = MatSetValues (matrix, 1, &petsc_i, 1, &petsc_j, + &value, ADD_VALUES); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + last_action = LastAction::add; + } + + + PetscScalar + MatrixBase::el (const unsigned int i, + const unsigned int j) const + { + const signed int petsc_i = i; + const signed int petsc_j = j; + PetscScalar value; + + const int ierr + = MatGetValues (matrix, 1, &petsc_i, 1, &petsc_j, + &value); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return value; + } + + + void + MatrixBase::compress () + { + // flush buffers + int ierr; + ierr = MatAssemblyBegin (matrix,MAT_FINAL_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = MatAssemblyEnd (matrix,MAT_FINAL_ASSEMBLY); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // try to compress the representation + ierr = MatCompress (matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + unsigned int + MatrixBase::m () const + { + int n_rows, n_cols; + int ierr = MatGetSize (matrix, &n_rows, &n_cols); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return n_rows; + } + + + + unsigned int + MatrixBase::n () const + { + int n_rows, n_cols; + int ierr = MatGetSize (matrix, &n_rows, &n_cols); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return n_cols; + } + + + + unsigned int + MatrixBase::n_nonzero_elements () const + { + MatInfo mat_info; + const int ierr + = MatGetInfo (matrix, MAT_GLOBAL_SUM, &mat_info); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return static_cast(mat_info.nz_used); + } + + + + PetscReal + MatrixBase::l1_norm () const + { + PetscReal result; + + const int ierr + = MatNorm (matrix, NORM_1, &result); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return result; + } + + + + PetscReal + MatrixBase::linfty_norm () const + { + PetscReal result; + + const int ierr + = MatNorm (matrix, NORM_INFINITY, &result); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return result; + } + + + + PetscReal + MatrixBase::frobenius_norm () const + { + PetscReal result; + + const int ierr + = MatNorm (matrix, NORM_FROBENIUS, &result); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return result; + } + + + + MatrixBase & + MatrixBase::operator *= (const PetscScalar a) + { + const int ierr + = MatScale (&a, matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + MatrixBase & + MatrixBase::operator /= (const PetscScalar a) + { + const PetscScalar factor = 1./a; + + const int ierr + = MatScale (&factor, matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + void + MatrixBase::vmult (VectorBase &dst, + const VectorBase &src) const + { + Assert (&src != &dst, ExcSourceEqualsDestination()); + + const int ierr = MatMult (matrix, src, dst); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + MatrixBase::Tvmult (VectorBase &dst, + const VectorBase &src) const + { + Assert (&src != &dst, ExcSourceEqualsDestination()); + + const int ierr = MatMultTranspose (matrix, src, dst); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + MatrixBase::vmult_add (VectorBase &dst, + const VectorBase &src) const + { + Assert (&src != &dst, ExcSourceEqualsDestination()); + + const int ierr = MatMultAdd (matrix, src, dst, dst); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + MatrixBase::Tvmult_add (VectorBase &dst, + const VectorBase &src) const + { + Assert (&src != &dst, ExcSourceEqualsDestination()); + + const int ierr = MatMultTransposeAdd (matrix, src, dst, dst); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + PetscScalar + MatrixBase::matrix_norm_square (const VectorBase &v) const + { + Vector tmp(v.size()); + vmult (tmp, v); + return tmp*v; + } + + + + PetscScalar + MatrixBase::matrix_scalar_product (const VectorBase &u, + const VectorBase &v) const + { + Vector tmp(v.size()); + vmult (tmp, v); + return u*tmp; + } + + + + double + MatrixBase::residual (VectorBase &dst, + const VectorBase &x, + const VectorBase &b) const + { + // avoid the use of a temporary, and + // rather do one negation pass more than + // necessary + vmult (dst, x); + dst -= b; + dst *= -1; + + return dst.l2_norm(); + } + + + + MatrixBase::operator const Mat () const + { + return matrix; + } +} + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_precondition.cc b/deal.II/lac/source/petsc_precondition.cc new file mode 100644 index 0000000000..3d1cf5db87 --- /dev/null +++ b/deal.II/lac/source/petsc_precondition.cc @@ -0,0 +1,240 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include +#include + +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + PreconditionerBase::PreconditionerBase (const MatrixBase &matrix) + : + matrix (matrix) + {} + + + + PreconditionerBase::~PreconditionerBase () + {} + + + + PreconditionerBase::operator const Mat () const + { + return matrix; + } + + +/* ----------------- PreconditionJacobi -------------------- */ + + + PreconditionJacobi::PreconditionJacobi (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionJacobi::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCJACOBI)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ----------------- PreconditionSOR -------------------- */ + + PreconditionSOR::AdditionalData:: + AdditionalData (const double omega) + : + omega (omega) + {} + + + + PreconditionSOR::PreconditionSOR (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionSOR::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCSOR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // then set flags as given + ierr = PCSORSetOmega (pc, additional_data.omega); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ----------------- PreconditionSSOR -------------------- */ + + PreconditionSSOR::AdditionalData:: + AdditionalData (const double omega) + : + omega (omega) + {} + + + + PreconditionSSOR::PreconditionSSOR (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionSSOR::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCSOR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // then set flags as given + ierr = PCSORSetOmega (pc, additional_data.omega); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // convert SOR to SSOR + ierr = PCSORSetSymmetric (pc, SOR_SYMMETRIC_SWEEP); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ----------------- PreconditionEisenstat -------------------- */ + + PreconditionEisenstat::AdditionalData:: + AdditionalData (const double omega) + : + omega (omega) + {} + + + + PreconditionEisenstat::PreconditionEisenstat (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionEisenstat::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCEISENSTAT)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // then set flags as given + ierr = PCEisenstatSetOmega (pc, additional_data.omega); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ----------------- PreconditionICC -------------------- */ + + + PreconditionICC::AdditionalData:: + AdditionalData (const unsigned int levels) + : + levels (levels) + {} + + + + PreconditionICC::PreconditionICC (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionICC::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCICC)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // then set flags + PCICCSetLevels (pc, additional_data.levels); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ----------------- PreconditionILU -------------------- */ + + PreconditionILU::AdditionalData:: + AdditionalData (const unsigned int levels) + : + levels (levels) + {} + + + + PreconditionILU::PreconditionILU (const MatrixBase &matrix, + const AdditionalData &additional_data) + : + PreconditionerBase (matrix), + additional_data (additional_data) + {} + + + void + PreconditionILU::set_preconditioner_type (PC &pc) const + { + // set the right type for the + // preconditioner + int ierr; + ierr = PCSetType (pc, const_cast(PCILU)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // then set flags + PCILUSetLevels (pc, additional_data.levels); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +} + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_solver.cc b/deal.II/lac/source/petsc_solver.cc new file mode 100644 index 0000000000..70c6abc2f9 --- /dev/null +++ b/deal.II/lac/source/petsc_solver.cc @@ -0,0 +1,479 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include +#include +#include + +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + SolverBase::SolverBase (SolverControl &cn, + MPI_Comm &mpi_communicator) + : + solver_control (cn), + mpi_communicator (mpi_communicator) + {} + + + + SolverBase::~SolverBase () + {} + + + + void + SolverBase::solve (const MatrixBase &A, + VectorBase &x, + const VectorBase &b, + const PreconditionerBase &preconditioner) const + { + int ierr; + + // first create a solver object + SLES sles; + ierr = SLESCreate (mpi_communicator, &sles); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // set the matrices involved. the + // last argument is irrelevant here, + // since we use the solver only once + // anyway + ierr = SLESSetOperators (sles, A, preconditioner, + SAME_PRECONDITIONER); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // let derived classes set the solver + // type, and the preconditioning object + // set the type of preconditioner + KSP ksp; + ierr = SLESGetKSP (sles, &ksp); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + set_solver_type (ksp); + + PC pc; + ierr = SLESGetPC (sles, &pc); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + preconditioner.set_preconditioner_type (pc); + + // in the deal.II solvers, we always + // honor the initial guess in the + // solution vector. do so here as well: + KSPSetInitialGuessNonzero (ksp, PETSC_TRUE); + + // then a convergence monitor + // function. that function simply checks + // with the solver_control object we have + // in this object for convergence + KSPSetConvergenceTest (ksp, &convergence_test, + reinterpret_cast(&solver_control)); + + // then do the real work: set up solver + // internal data and solve the + // system. this could be joined in one + // operation, but it is recommended this + // way to be able to separate statistic + // output if requested + int iterations = 0; + ierr = SLESSetUp (sles, b, x); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = SLESSolve (sles, b, x, &iterations); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // and destroy the solver object + ierr = SLESDestroy (sles); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // in case of failure: throw + // exception + if (solver_control.last_check() != SolverControl::success) + throw SolverControl::NoConvergence (solver_control.last_step(), + solver_control.last_value()); + // otherwise exit as normal + } + + + + SolverControl & + SolverBase::control() const + { + return solver_control; + } + + + + int + SolverBase::convergence_test (KSP /*ksp*/, + const int iteration, + const double residual_norm, + KSPConvergedReason *reason, + void *solver_control_x) + { + SolverControl &solver_control = *reinterpret_cast(solver_control_x); + + const SolverControl::State state + = solver_control.check (iteration, residual_norm); + + switch (state) + { + case ::SolverControl::iterate: + *reason = KSP_CONVERGED_ITERATING; + break; + + case ::SolverControl::success: + *reason = static_cast(1); + break; + + case ::SolverControl::failure: + if (solver_control.last_step() > solver_control.max_steps()) + *reason = KSP_DIVERGED_ITS; + else + *reason = KSP_DIVERGED_DTOL; + break; + + default: + Assert (false, ExcNotImplemented()); + } + + // return without failure + return 0; + } + + + +/* ---------------------- SolverRichardson ------------------------ */ + + + SolverRichardson::AdditionalData:: + AdditionalData (const double omega) + : + omega (omega) + {} + + + + SolverRichardson::SolverRichardson (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverRichardson::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPRICHARDSON)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // set the damping factor from the data + ierr = KSPRichardsonSetScale (ksp, additional_data.omega); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverChebychev ------------------------ */ + + SolverChebychev::SolverChebychev (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverChebychev::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPCHEBYCHEV)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverCG ------------------------ */ + + SolverCG::SolverCG (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverCG::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPCG)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverBiCG ------------------------ */ + + SolverBiCG::SolverBiCG (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverBiCG::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPBICG)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverGMRES ------------------------ */ + + SolverGMRES::AdditionalData:: + AdditionalData (const unsigned int restart_parameter) + : + restart_parameter (restart_parameter) + {} + + + + SolverGMRES::SolverGMRES (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverGMRES::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPGMRES)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // set the restart parameter from the + // data. we would like to use the simple + // code that is commented out, but this + // leads to nasty warning and error + // messages due to some stupidity on + // PETSc's side: KSPGMRESSetRestart is + // implemented as a macro in which return + // statements are hidden. This may work + // if people strictly follow the PETSc + // coding style of always having + // functions return an integer error + // code, but the present function isn't + // like this. +/* + ierr = KSPGMRESSetRestart (ksp, additional_data.restart_parameter); + AssertThrow (ierr == 0, ExcPETScError(ierr)); +*/ + // so rather expand their macros by hand, + // and do some equally nast stuff that at + // least doesn't yield warnings... + int (*fun_ptr)(KSP,int); + ierr = PetscObjectQueryFunction((PetscObject)(ksp), + "KSPGMRESSetRestart_C", + (PetscVoidFunction)&fun_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = (*fun_ptr)(ksp,additional_data.restart_parameter); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverBicgstab ------------------------ */ + + SolverBicgstab::SolverBicgstab (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverBicgstab::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPBCGS)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverCGS ------------------------ */ + + SolverCGS::SolverCGS (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverCGS::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPCGS)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverTFQMR ------------------------ */ + + SolverTFQMR::SolverTFQMR (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverTFQMR::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPTFQMR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverTCQMR ------------------------ */ + + SolverTCQMR::SolverTCQMR (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverTCQMR::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPTCQMR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverCR ------------------------ */ + + SolverCR::SolverCR (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverCR::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPCR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +/* ---------------------- SolverLSQR ------------------------ */ + + SolverLSQR::SolverLSQR (SolverControl &cn, + MPI_Comm &mpi_communicator, + const AdditionalData &data) + : + SolverBase (cn, mpi_communicator), + additional_data (data) + {} + + + void + SolverLSQR::set_solver_type (KSP &ksp) const + { + // set the type of solver. work around a + // problem in PETSc 2.1.6, where it asks + // for a char*, even though KSPXXXX is of + // type const char* + int ierr; + ierr = KSPSetType (ksp, const_cast(KSPLSQR)); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + +} + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_sparse_matrix.cc b/deal.II/lac/source/petsc_sparse_matrix.cc new file mode 100644 index 0000000000..2099cf219f --- /dev/null +++ b/deal.II/lac/source/petsc_sparse_matrix.cc @@ -0,0 +1,81 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + SparseMatrix::SparseMatrix (const unsigned int m, + const unsigned int n, + const unsigned int n_nonzero_per_row, + const bool is_symmetric) + { + // use the call sequence indicating only + // a maximal number of elements per row + // for all rows globally + const int ierr + = MatCreateSeqAIJ(PETSC_COMM_SELF, m, n, n_nonzero_per_row, + 0, &matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // set symmetric flag, if so requested + if (is_symmetric == true) + { + const int ierr + = MatSetOption (matrix, MAT_SYMMETRIC); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + } + + + + SparseMatrix::SparseMatrix (const unsigned int m, + const unsigned int n, + const std::vector &row_lengths, + const bool is_symmetric) + { + Assert (row_lengths.size() == m, + ExcDimensionMismatch (row_lengths.size(), m)); + + // use the call sequence indicating a + // maximal number of elements for each + // row individually. annoyingly, we + // always use unsigned ints for cases + // like this, while PETSc wants to see + // signed integers. so we have to + // convert, unless we want to play dirty + // tricks with conversions of pointers + const std::vector int_row_lengths (row_lengths.begin(), + row_lengths.end()); + const int ierr + = MatCreateSeqAIJ(PETSC_COMM_SELF, m, n, 0, + &int_row_lengths[0], &matrix); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // set symmetric flag, if so requested + if (is_symmetric == true) + { + const int ierr + = MatSetOption (matrix, MAT_SYMMETRIC); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + } +} + + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_vector.cc b/deal.II/lac/source/petsc_vector.cc new file mode 100644 index 0000000000..cf3fdea4ae --- /dev/null +++ b/deal.II/lac/source/petsc_vector.cc @@ -0,0 +1,64 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include + +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + + + Vector::Vector () + { + const int n = 0; + const int ierr + = VecCreateSeq (PETSC_COMM_SELF, n, &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + Vector::Vector (const unsigned int n) + { + const int ierr + = VecCreateSeq (PETSC_COMM_SELF, n, &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + Vector::Vector (const VectorBase &v) + { + int ierr + = VecCreateSeq (PETSC_COMM_SELF, v.size(), &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + VectorBase::operator = (v); + } + + + void + Vector::create_vector (const unsigned int n) + { + const int ierr + = VecCreateSeq (PETSC_COMM_SELF, n, &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } +} + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/petsc_vector_base.cc b/deal.II/lac/source/petsc_vector_base.cc new file mode 100644 index 0000000000..2c334ded2c --- /dev/null +++ b/deal.II/lac/source/petsc_vector_base.cc @@ -0,0 +1,667 @@ +//--------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2004 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +#include + +#include + +#ifdef DEAL_II_USE_PETSC + + +namespace PETScWrappers +{ + VectorBase::VectorBase () + {} + + + + VectorBase::VectorBase (const VectorBase &v) + { + int ierr = VecDuplicate (v.vector, &vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + ierr = VecCopy (v.vector, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + VectorBase::~VectorBase () + { + const int ierr = VecDestroy (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::reinit (const unsigned int n, + const bool fast) + { + // only do something if the sizes + // mismatch + if (size() != n) + { + // FIXME: I'd like to use this here, + // but somehow it leads to odd errors + // somewhere down the line in some of + // the tests: +// const int ierr = VecSetSizes (vector, n, n); +// AssertThrow (ierr == 0, ExcPETScError(ierr)); + + // so let's go the slow way: + int ierr; + ierr = VecDestroy (vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + create_vector (n); + } + + // finally clear the new vector if so + // desired + if (fast == false) + *this = 0; + } + + + + void + VectorBase::reinit (const VectorBase &v, + const bool fast) + { + reinit (v.size(), fast); + } + + + + void + VectorBase::clear () + { + const PetscScalar zero = 0; + const int ierr = VecSet (&zero, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + VectorBase & + VectorBase::operator = (const PetscScalar s) + { + const int ierr = VecSet (&s, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + VectorBase & + VectorBase::operator = (const VectorBase &v) + { + // if the vectors have different sizes, + // then first resize the present one + if (size() != v.size()) + reinit (v.size(), true); + + const int ierr = VecCopy (v.vector, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + bool + VectorBase::operator == (const VectorBase &v) const + { + Assert (size() == v.size(), + ExcDimensionMismatch(size(), v.size())); + + PetscTruth flag; + + const int ierr = VecEqual (vector, v.vector, &flag); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return (flag == PETSC_TRUE); + } + + + bool + VectorBase::operator != (const VectorBase &v) const + { + Assert (size() == v.size(), + ExcDimensionMismatch(size(), v.size())); + + PetscTruth flag; + + const int ierr = VecEqual (vector, v.vector, &flag); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return (flag == PETSC_FALSE); + } + + + unsigned int + VectorBase::size () const + { + int sz; + const int ierr = VecGetSize (vector, &sz); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return sz; + } + + + + PetscScalar + VectorBase::operator * (const VectorBase &vec) const + { + Assert (size() == vec.size(), + ExcDimensionMismatch(size(), vec.size())); + + PetscScalar result; + + const int ierr = VecDot (vector, vec.vector, &result); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return result; + } + + + + void + VectorBase::compress () + { + int ierr; + ierr = VecAssemblyBegin(vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + ierr = VecAssemblyEnd(vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + PetscScalar + VectorBase::norm_sqr () const + { + const PetscScalar d = l2_norm(); + return d*d; + } + + + + PetscScalar + VectorBase::mean_value () const + { + // get a representation of the vector and + // loop over all the elements + PetscScalar *start_ptr; + int ierr = VecGetArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + PetscScalar mean = 0; + { + PetscScalar sum0 = 0, + sum1 = 0, + sum2 = 0, + sum3 = 0; + + // use modern processors better by + // allowing pipelined commands to be + // executed in parallel + const PetscScalar * ptr = start_ptr; + const PetscScalar * eptr = ptr + (size()/4)*4; + while (ptr!=eptr) + { + sum0 += *ptr++; + sum1 += *ptr++; + sum2 += *ptr++; + sum3 += *ptr++; + }; + // add up remaining elements + while (ptr != start_ptr+size()) + sum0 += *ptr++; + + mean = (sum0+sum1+sum2+sum3)/size(); + } + + // restore the representation of the + // vector + ierr = VecRestoreArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return mean; + } + + + + PetscScalar + VectorBase::l1_norm () const + { + PetscScalar d; + + const int ierr = VecNorm (vector, NORM_1, &d); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return d; + } + + + + PetscScalar + VectorBase::l2_norm () const + { + PetscScalar d; + + const int ierr = VecNorm (vector, NORM_2, &d); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return d; + } + + + + PetscScalar + VectorBase::lp_norm (const PetscScalar p) const + { + // get a representation of the vector and + // loop over all the elements + PetscScalar *start_ptr; + int ierr = VecGetArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + PetscScalar norm = 0; + { + PetscScalar sum0 = 0, + sum1 = 0, + sum2 = 0, + sum3 = 0; + + // use modern processors better by + // allowing pipelined commands to be + // executed in parallel + const PetscScalar * ptr = start_ptr; + const PetscScalar * eptr = ptr + (size()/4)*4; + while (ptr!=eptr) + { + sum0 += std::pow(std::fabs(*ptr++), p); + sum1 += std::pow(std::fabs(*ptr++), p); + sum2 += std::pow(std::fabs(*ptr++), p); + sum3 += std::pow(std::fabs(*ptr++), p); + }; + // add up remaining elements + while (ptr != start_ptr+size()) + sum0 += std::pow(std::fabs(*ptr++), p); + + norm = std::pow(sum0+sum1+sum2+sum3, + static_cast(1./p)); + } + + // restore the representation of the + // vector + ierr = VecRestoreArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return norm; + } + + + + PetscScalar + VectorBase::linfty_norm () const + { + PetscScalar d; + + const int ierr = VecNorm (vector, NORM_INFINITY, &d); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return d; + } + + + + bool + VectorBase::all_zero () const + { + // get a representation of the vector and + // loop over all the elements + PetscScalar *start_ptr; + int ierr = VecGetArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + const PetscScalar *ptr = start_ptr, + *eptr = start_ptr + size(); + bool flag = true; + while (ptr != eptr) + { + if (*ptr != 0) + { + flag = false; + break; + } + ++ptr; + } + + // restore the representation of the + // vector + ierr = VecRestoreArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return flag; + } + + + + bool + VectorBase::is_non_negative () const + { + // get a representation of the vector and + // loop over all the elements + PetscScalar *start_ptr; + int ierr = VecGetArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + const PetscScalar *ptr = start_ptr, + *eptr = start_ptr + size(); + bool flag = true; + while (ptr != eptr) + { + if (*ptr < 0.0) + { + flag = false; + break; + } + ++ptr; + } + + // restore the representation of the + // vector + ierr = VecRestoreArray (vector, &start_ptr); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return flag; + } + + + + VectorBase & + VectorBase::operator *= (const PetscScalar a) + { + const int ierr + = VecScale (&a, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + VectorBase & + VectorBase::operator /= (const PetscScalar a) + { + const PetscScalar factor = 1./a; + + const int ierr + = VecScale (&factor, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + VectorBase & + VectorBase::operator += (const VectorBase &v) + { + const PetscScalar one = 1.0; + + const int ierr + = VecAXPY (&one, v, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + VectorBase & + VectorBase::operator -= (const VectorBase &v) + { + const PetscScalar minus_one = -1.0; + + const int ierr + = VecAXPY (&minus_one, v, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + return *this; + } + + + + void + VectorBase::add (const PetscScalar s) + { + const int ierr + = VecShift (&s, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::add (const VectorBase &v) + { + *this += v; + } + + + + void + VectorBase::add (const PetscScalar a, + const VectorBase &v) + { + const int ierr + = VecAXPY (&a, v, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::add (const PetscScalar a, + const VectorBase &v, + const PetscScalar b, + const VectorBase &w) + { + const PetscScalar weights[2] = {a,b}; + Vec addends[2] = {v.vector, w.vector}; + + const int ierr + = VecMAXPY (2, weights, vector, addends); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::sadd (const PetscScalar s, + const VectorBase &v) + { + const int ierr + = VecAYPX (&s, v, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &v) + { + // there is nothing like a AXPAY + // operation in Petsc, so do it in two + // steps + *this *= s; + add (a,v); + } + + + + void + VectorBase::sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &v, + const PetscScalar b, + const VectorBase &w) + { + // there is no operation like MAXPAY, so + // do it in two steps + *this *= s; + + const PetscScalar weights[2] = {a,b}; + Vec addends[2] = {v.vector,w.vector}; + + const int ierr + = VecMAXPY (2, weights, vector, addends); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::sadd (const PetscScalar s, + const PetscScalar a, + const VectorBase &v, + const PetscScalar b, + const VectorBase &w, + const PetscScalar c, + const VectorBase &x) + { + // there is no operation like MAXPAY, so + // do it in two steps + *this *= s; + + const PetscScalar weights[3] = {a,b,c}; + Vec addends[3] = {v.vector, w.vector, x.vector}; + + const int ierr + = VecMAXPY (3, weights, vector, addends); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::scale (const VectorBase &factors) + { + const int ierr + = VecPointwiseMult (vector, factors, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::equ (const PetscScalar a, + const VectorBase &v) + { + // there is no simple operation for this + // in PETSc. there are multiple ways to + // emulate it, we choose this one: + *this = v; + *this *= a; + } + + + + void + VectorBase::equ (const PetscScalar a, + const VectorBase &v, + const PetscScalar b, + const VectorBase &w) + { + // there is no simple operation for this + // in PETSc. there are multiple ways to + // emulate it, we choose this one: + *this = v; + sadd (a, b, w); + } + + + + void + VectorBase::ratio (const VectorBase &a, + const VectorBase &b) + { + const int ierr + = VecPointwiseDivide (a, b, vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + void + VectorBase::print (std::ostream &out, + const unsigned int precision, + const bool scientific, + const bool across) const + { + AssertThrow (out, ExcIO()); + + // get a representation of the vector and + // loop over all the elements + PetscScalar *val; + int ierr = VecGetArray (vector, &val); + + AssertThrow (ierr == 0, ExcPETScError(ierr)); + out.precision (precision); + if (scientific) + out.setf (std::ios::scientific, std::ios::floatfield); + else + out.setf (std::ios::fixed, std::ios::floatfield); + + if (across) + for (unsigned int i=0; i(val[i]) << ' '; + else + for (unsigned int i=0; i(val[i]) << std::endl; + out << std::endl; + + // restore the representation of the + // vector + ierr = VecRestoreArray (vector, &val); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + AssertThrow (out, ExcIO()); + } + + + void + VectorBase::swap (VectorBase &v) + { + const int ierr = VecSwap (vector, v.vector); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + } + + + + VectorBase::operator const Vec & () const + { + return vector; + } + +} + +#endif // DEAL_II_USE_PETSC diff --git a/deal.II/lac/source/sparsity_pattern.cc b/deal.II/lac/source/sparsity_pattern.cc index f99b09d698..74de399834 100644 --- a/deal.II/lac/source/sparsity_pattern.cc +++ b/deal.II/lac/source/sparsity_pattern.cc @@ -28,7 +28,8 @@ const unsigned int SparsityPattern::invalid_entry; -SparsityPattern::SparsityPattern () : +SparsityPattern::SparsityPattern () + : max_dim(0), max_vec_len(0), rowstart(0), @@ -41,7 +42,8 @@ SparsityPattern::SparsityPattern () : -SparsityPattern::SparsityPattern (const SparsityPattern &s) : +SparsityPattern::SparsityPattern (const SparsityPattern &s) + : Subscriptor(), max_dim(0), max_vec_len(0), @@ -64,12 +66,13 @@ SparsityPattern::SparsityPattern (const unsigned int m, const unsigned int n, const unsigned int max_per_row, const bool optimize_diag) - : max_dim(0), - max_vec_len(0), - rowstart(0), - colnums(0), - compressed(false), - diagonal_optimized(false) + : + max_dim(0), + max_vec_len(0), + rowstart(0), + colnums(0), + compressed(false), + diagonal_optimized(false) { reinit (m,n,max_per_row, optimize_diag); } @@ -80,10 +83,11 @@ SparsityPattern::SparsityPattern (const unsigned int m, const unsigned int n, const std::vector &row_lengths, const bool optimize_diag) - : max_dim(0), - max_vec_len(0), - rowstart(0), - colnums(0) + : + max_dim(0), + max_vec_len(0), + rowstart(0), + colnums(0) { reinit (m, n, row_lengths, optimize_diag); } @@ -92,10 +96,11 @@ SparsityPattern::SparsityPattern (const unsigned int m, SparsityPattern::SparsityPattern (const unsigned int n, const unsigned int max_per_row) - : max_dim(0), - max_vec_len(0), - rowstart(0), - colnums(0) + : + max_dim(0), + max_vec_len(0), + rowstart(0), + colnums(0) { reinit (n, n, max_per_row, true); } @@ -105,10 +110,11 @@ SparsityPattern::SparsityPattern (const unsigned int n, SparsityPattern::SparsityPattern (const unsigned int m, const std::vector &row_lengths, const bool optimize_diag) - : max_dim(0), - max_vec_len(0), - rowstart(0), - colnums(0) + : + max_dim(0), + max_vec_len(0), + rowstart(0), + colnums(0) { reinit (m, m, row_lengths, optimize_diag); } @@ -116,12 +122,13 @@ SparsityPattern::SparsityPattern (const unsigned int m, SparsityPattern::SparsityPattern (const SparsityPattern &original, - const unsigned int max_per_row, - const unsigned int extra_off_diagonals) - : max_dim(0), - max_vec_len(0), - rowstart(0), - colnums(0) + const unsigned int max_per_row, + const unsigned int extra_off_diagonals) + : + max_dim(0), + max_vec_len(0), + rowstart(0), + colnums(0) { Assert (original.rows==original.cols, ExcNotQuadratic()); Assert (original.optimize_diagonal(), ExcNotQuadratic()); diff --git a/deal.II/lac/source/vector.cc b/deal.II/lac/source/vector.cc index 9bc71c7671..2b67288db4 100644 --- a/deal.II/lac/source/vector.cc +++ b/deal.II/lac/source/vector.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -17,6 +17,8 @@ // explicit instantiations template class Vector; template Vector& Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator=(const Vector&); +template bool Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator==(const Vector&); +template bool Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator==(const Vector&); template double Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator*(const Vector&) const; template double Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator*(const Vector&) const; template void Vector::reinit(const Vector&, const bool); @@ -28,6 +30,8 @@ template void Vector::scale(const Vector&); template class Vector; template Vector& Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator=(const Vector&); +template bool Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator==(const Vector&); +template bool Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator==(const Vector&); template float Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator*(const Vector&) const; template float Vector::DEAL_II_MEMBER_OP_TEMPLATE_INST operator*(const Vector&) const; template void Vector::reinit(const Vector&, const bool); diff --git a/deal.II/lib/Makefile b/deal.II/lib/Makefile index f8bbb4a89c..a4364818ef 100644 --- a/deal.II/lib/Makefile +++ b/deal.II/lib/Makefile @@ -11,6 +11,55 @@ default: @echo There is no default target in this directory +######################### EXTERNAL LINK TARGETS ################### +# link in external libs, if any +external-links: external-links-petsc + +ifeq ($(USE_CONTRIB_PETSC),yes) + + # PETSc has the nasty habit of putting debug and optimized builds into + # different directories, but naming the respective libraries the same. + # Since one doesn't want to always set and reset $LD_LIBRARY_PATH when + # one switches from debug to optimized mode, they pass -Wl,-rpath to + # the linker line. This is not really portable, and it has the additional + # drawback that one has to pass different linker flags for debug and + # optimized mode. The latter is a problem with our present build system, + # which allows to use different libraries, but doesn't take into account + # that one may want to pass different $LDFLAGS. + # + # To avoid such hassle, we build some kind of convenience library: a shared + # library that has no content, but contains references to all the different + # PETSc libraries, and we build one for debug and one for optimized mode. + # We can't really get around the use of -Wl,-rpath, but at least we + # have now centralized this part to one single place, and are back to where + # we want to be: have different libraries for debug and optimized mode, + # but in the same directory. And, voila, our build system works again :-) + lib-contrib-petsc-path.g = $(DEAL_II_PETSC_DIR)/lib/libg_c++/$(DEAL_II_PETSC_ARCH) + lib-contrib-petsc-path.o = $(DEAL_II_PETSC_DIR)/lib/libO_c++/$(DEAL_II_PETSC_ARCH) + xlib.g = $(lib-contrib-petsc-path.g)/libpetscsles.so \ + $(lib-contrib-petsc-path.g)/libpetscdm.so \ + $(lib-contrib-petsc-path.g)/libpetscmat.so \ + $(lib-contrib-petsc-path.g)/libpetscvec.so \ + $(lib-contrib-petsc-path.g)/libpetsc.so + xlib.o = $(lib-contrib-petsc-path.o)/libpetscsles.so \ + $(lib-contrib-petsc-path.o)/libpetscdm.so \ + $(lib-contrib-petsc-path.o)/libpetscmat.so \ + $(lib-contrib-petsc-path.o)/libpetscvec.so \ + $(lib-contrib-petsc-path.o)/libpetsc.so + external-links-petsc: + @echo Setting up libraries for PETSc + @$(CXX) -shared -o libpetsc_g.so \ + -Wl,-rpath,$(lib-contrib-petsc-path.g) $(xlib.g) + @$(CXX) -shared -o libpetsc_o.so \ + -Wl,-rpath,$(lib-contrib-petsc-path.o) $(xlib.o) + +else + external-links-petsc: +endif + + + +######################### CLEAN TARGETS ################### # clean everything clean: clean-objects clean-bin @@ -38,3 +87,4 @@ distclean: clean .PHONY: clean clean-objects .PHONY: clean-base clean-lac clean-1d clean-2d clean-3d .PHONY: clean-contrib +.PHONY: external-links external-links-petsc