diff --git a/AMDiS/libtool b/AMDiS/libtool index 4f4afd67949bd025c4883ad68bf263c224fa9462..db01bc59718f48797b60d36d16c9ae7d8fd0eab2 100755 --- a/AMDiS/libtool +++ b/AMDiS/libtool @@ -30,10 +30,10 @@ # the same distribution terms that you use for the rest of that program. # A sed program that does not truncate output. -SED="/usr/bin/sed" +SED="/bin/sed" # Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="/usr/bin/sed -e 1s/^X//" +Xsed="/bin/sed -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. @@ -44,7 +44,7 @@ available_tags=" CXX F77" # ### BEGIN LIBTOOL CONFIG -# Libtool was configured on host p2s103: +# Libtool was configured on host NWRW15: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -66,12 +66,12 @@ fast_install=yes # The host system. host_alias= -host=x86_64-unknown-linux-gnu +host=i686-redhat-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=x86_64-unknown-linux-gnu +build=i686-redhat-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -82,25 +82,25 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" +LTCC="gcc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" +CC="gcc" # Is the compiler the GNU C compiler? with_gcc=yes -gcc_dir=`gcc -print-file-name=. | /usr/bin/sed 's,/\.$,,'` +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` gcc_ver=`gcc -dumpversion` # An ERE matcher. EGREP="grep -E" # The linker used to build libraries. -LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" +LD="/usr/bin/ld" # Whether we need hard or soft links. LN_S="ln -s" @@ -174,7 +174,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="" +link_static_flag="-static" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -328,10 +328,10 @@ variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COM link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=`echo "/lib64 /usr/lib64 /usr/local/lib64" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../ /lib/i386-redhat-linux/4.1.2/ /lib/ /usr/lib/i386-redhat-linux/4.1.2/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /usr/X11R6/lib64/Xaw3d /usr/X11R6/lib64 /usr/X11R6/lib/Xaw3d /usr/X11R6/lib /usr/x86_64-suse-linux/lib /usr/local/lib64 /usr/local/lib /opt/kde3/lib64 /opt/kde3/lib /opt/gnome/lib64 /opt/gnome/lib /lib64 /lib /usr/lib64 /usr/lib /opt/cluster/intel/cce/9.1.042/lib /opt/cluster/intel/fce/9.1.036/lib /opt/cluster/Pathscale3.0/lib/2.9.99 /opt/cluster/Pathscale3.0/lib/2.9.99/32 /work/licsoft/compilers/pgi/linux86-64/6.2/lib /work/licsoft/compilers/pgi/linux86-64/6.2/libso " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -7266,7 +7266,7 @@ disable_libs=static # End: # ### BEGIN LIBTOOL TAG CONFIG: CXX -# Libtool was configured on host p2s103: +# Libtool was configured on host NWRW15: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -7288,12 +7288,12 @@ fast_install=yes # The host system. host_alias= -host=x86_64-unknown-linux-gnu +host=i686-redhat-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=x86_64-unknown-linux-gnu +build=i686-redhat-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -7304,25 +7304,25 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" +LTCC="gcc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpiCC" +CC="g++" # Is the compiler the GNU C compiler? with_gcc=yes -gcc_dir=`gcc -print-file-name=. | /usr/bin/sed 's,/\.$,,'` +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` gcc_ver=`gcc -dumpversion` # An ERE matcher. EGREP="grep -E" # The linker used to build libraries. -LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" +LD="/usr/bin/ld" # Whether we need hard or soft links. LN_S="ln -s" @@ -7396,7 +7396,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="" +link_static_flag="-static" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -7451,11 +7451,11 @@ striplib="strip --strip-unneeded" # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=`echo "/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbeginS.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +predep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginS.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=`echo "/usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtendS.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +postdep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.2/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place before the objects being linked to create a # shared library. @@ -7463,11 +7463,11 @@ predeps="" # Dependencies to place after the objects being linked to create a # shared library. -postdeps="-lmpi_cxx -lmpi -lopen-rte -lopen-pal -libverbs -lrt -lnuma -ldl -lnsl -lutil -ldl -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s" +postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=`echo "-L/usr/lib64 -L/licsoft/libraries/openmpi/1.2.6/64bit/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.." | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +compiler_lib_search_path=`echo "-L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -7547,10 +7547,10 @@ variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COM link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=`echo "/lib64 /usr/lib64 /usr/local/lib64" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../ /lib/i386-redhat-linux/4.1.2/ /lib/ /usr/lib/i386-redhat-linux/4.1.2/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /usr/X11R6/lib64/Xaw3d /usr/X11R6/lib64 /usr/X11R6/lib/Xaw3d /usr/X11R6/lib /usr/x86_64-suse-linux/lib /usr/local/lib64 /usr/local/lib /opt/kde3/lib64 /opt/kde3/lib /opt/gnome/lib64 /opt/gnome/lib /lib64 /lib /usr/lib64 /usr/lib /opt/cluster/intel/cce/9.1.042/lib /opt/cluster/intel/fce/9.1.036/lib /opt/cluster/Pathscale3.0/lib/2.9.99 /opt/cluster/Pathscale3.0/lib/2.9.99/32 /work/licsoft/compilers/pgi/linux86-64/6.2/lib /work/licsoft/compilers/pgi/linux86-64/6.2/libso " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -7574,7 +7574,7 @@ include_expsyms="" # ### BEGIN LIBTOOL TAG CONFIG: F77 -# Libtool was configured on host p2s103: +# Libtool was configured on host NWRW15: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -7596,12 +7596,12 @@ fast_install=yes # The host system. host_alias= -host=x86_64-unknown-linux-gnu +host=i686-redhat-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=x86_64-unknown-linux-gnu +build=i686-redhat-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -7612,7 +7612,7 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" +LTCC="gcc" # LTCC compiler flags. LTCFLAGS="-g -O2" @@ -7621,16 +7621,16 @@ LTCFLAGS="-g -O2" CC="g77" # Is the compiler the GNU C compiler? -with_gcc= +with_gcc=yes -gcc_dir=`gcc -print-file-name=. | /usr/bin/sed 's,/\.$,,'` +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` gcc_ver=`gcc -dumpversion` # An ERE matcher. EGREP="grep -E" # The linker used to build libraries. -LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" +LD="/usr/bin/ld" # Whether we need hard or soft links. LN_S="ln -s" @@ -7858,10 +7858,10 @@ variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COM link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=`echo "/lib64 /usr/lib64 /usr/local/lib64" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../i386-redhat-linux/lib/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../ /lib/i386-redhat-linux/3.4.6/ /lib/ /usr/lib/i386-redhat-linux/3.4.6/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /usr/X11R6/lib64/Xaw3d /usr/X11R6/lib64 /usr/X11R6/lib/Xaw3d /usr/X11R6/lib /usr/x86_64-suse-linux/lib /usr/local/lib64 /usr/local/lib /opt/kde3/lib64 /opt/kde3/lib /opt/gnome/lib64 /opt/gnome/lib /lib64 /lib /usr/lib64 /usr/lib /opt/cluster/intel/cce/9.1.042/lib /opt/cluster/intel/fce/9.1.036/lib /opt/cluster/Pathscale3.0/lib/2.9.99 /opt/cluster/Pathscale3.0/lib/2.9.99/32 /work/licsoft/compilers/pgi/linux86-64/6.2/lib /work/licsoft/compilers/pgi/linux86-64/6.2/libso " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" diff --git a/AMDiS/src/AdaptBase.h b/AMDiS/src/AdaptBase.h index 77bdc46dccce1428dfa29ec26888d5744db39ee5..83660464d99cda495369e6ebaa0a9b0ab2ecd3c1 100644 --- a/AMDiS/src/AdaptBase.h +++ b/AMDiS/src/AdaptBase.h @@ -43,14 +43,14 @@ namespace AMDiS { /** \brief * Constructor */ - AdaptBase(const ::std::string& name, + AdaptBase(const ::std::string& name, ProblemIterationInterface *problemIteration, - AdaptInfo *adaptInfo_, - ProblemTimeInterface *problemTime = NULL, - AdaptInfo *initialAdaptInfo = NULL) + AdaptInfo *adaptInfo, + ProblemTimeInterface *problemTime = NULL, + AdaptInfo *initialAdaptInfo = NULL) : name_(name), problemIteration_(problemIteration), - adaptInfo(adaptInfo_), + adaptInfo_(adaptInfo), problemTime_(problemTime), initialAdaptInfo_(initialAdaptInfo) {}; @@ -85,10 +85,10 @@ namespace AMDiS { }; /** \brief - * Returns \ref adaptInfo + * Returns \ref adaptInfo_ */ inline AdaptInfo *getAdaptInfo() { - return adaptInfo; + return adaptInfo_; }; /** \brief @@ -123,7 +123,7 @@ namespace AMDiS { /** \brief * Main adapt info */ - AdaptInfo *adaptInfo; + AdaptInfo *adaptInfo_; /** \brief * problem time interface diff --git a/AMDiS/src/AdaptInstationary.cc b/AMDiS/src/AdaptInstationary.cc index c23cb21b1c1565b82cb17f50d34d3bf45a5ae423..e6f67c8161a888cbca7f7dad13710dffb223a08c 100644 --- a/AMDiS/src/AdaptInstationary.cc +++ b/AMDiS/src/AdaptInstationary.cc @@ -77,24 +77,24 @@ namespace AMDiS { FUNCNAME("AdaptInstationary::explicitTimeStrategy()"); // estimate before first adaption - if (adaptInfo->getTime() <= adaptInfo->getStartTime()) { - problemIteration_->oneIteration(adaptInfo, ESTIMATE); + if (adaptInfo_->getTime() <= adaptInfo_->getStartTime()) { + problemIteration_->oneIteration(adaptInfo_, ESTIMATE); } // increment time - adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep()); + adaptInfo_->setTime(adaptInfo_->getTime() + adaptInfo_->getTimestep()); - problemTime_->setTime(adaptInfo); + problemTime_->setTime(adaptInfo_); INFO(info_,6)("time = %e, timestep = %e\n", - adaptInfo->getTime(), adaptInfo->getTimestep()); + adaptInfo_->getTime(), adaptInfo_->getTimestep()); - adaptInfo->setSpaceIteration(0); + adaptInfo_->setSpaceIteration(0); // do the iteration - problemIteration_->beginIteration(adaptInfo); - problemIteration_->oneIteration(adaptInfo, FULL_ITERATION); - problemIteration_->endIteration(adaptInfo); + problemIteration_->beginIteration(adaptInfo_); + problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION); + problemIteration_->endIteration(adaptInfo_); } void AdaptInstationary::implicitTimeStrategy() @@ -102,54 +102,54 @@ namespace AMDiS { FUNCNAME("AdaptInstationary::implicitTimeStrategy()"); do { - adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep()); - problemTime_->setTime(adaptInfo); + adaptInfo_->setTime(adaptInfo_->getTime() + adaptInfo_->getTimestep()); + problemTime_->setTime(adaptInfo_); INFO(info_,6)("time = %e, try timestep = %e\n", - adaptInfo->getTime(), adaptInfo->getTimestep()); + adaptInfo_->getTime(), adaptInfo_->getTimestep()); - problemIteration_->oneIteration(adaptInfo, NO_ADAPTION); + problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION); - adaptInfo->incTimestepIteration(); + adaptInfo_->incTimestepIteration(); if (!fixedTimestep_ && - !adaptInfo->timeToleranceReached() && - !adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) + !adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep()) { - adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep()); - adaptInfo->setTimestep(adaptInfo->getTimestep() * time_delta_1); + adaptInfo_->setTime(adaptInfo_->getTime() - adaptInfo_->getTimestep()); + adaptInfo_->setTimestep(adaptInfo_->getTimestep() * time_delta_1); continue; } - adaptInfo->setSpaceIteration(0); + adaptInfo_->setSpaceIteration(0); do { - problemIteration_->beginIteration(adaptInfo); + problemIteration_->beginIteration(adaptInfo_); - if (problemIteration_->oneIteration(adaptInfo, FULL_ITERATION)) { + if (problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION)) { if (!fixedTimestep_ && - !adaptInfo->timeToleranceReached() && - !adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) + !adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep()) { - adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep()); - adaptInfo->setTimestep(adaptInfo->getTimestep() * time_delta_1); - problemIteration_->endIteration(adaptInfo); - adaptInfo->incSpaceIteration(); + adaptInfo_->setTime(adaptInfo_->getTime() - adaptInfo_->getTimestep()); + adaptInfo_->setTimestep(adaptInfo_->getTimestep() * time_delta_1); + problemIteration_->endIteration(adaptInfo_); + adaptInfo_->incSpaceIteration(); break; } } - adaptInfo->incSpaceIteration(); - problemIteration_->endIteration(adaptInfo); + adaptInfo_->incSpaceIteration(); + problemIteration_->endIteration(adaptInfo_); - } while(!adaptInfo->spaceToleranceReached() && - adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration()); - } while(!adaptInfo->timeToleranceReached() && - !adaptInfo->getTimestep() <= adaptInfo->getMinTimestep() && - adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration()); + } while(!adaptInfo_->spaceToleranceReached() && + adaptInfo_->getSpaceIteration() <= adaptInfo_->getMaxSpaceIteration()); + } while(!adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep() && + adaptInfo_->getTimestepIteration() <= adaptInfo_->getMaxTimestepIteration()); - if (!fixedTimestep_ && adaptInfo->timeErrorLow()) { - adaptInfo->setTimestep(adaptInfo->getTimestep() *time_delta_2); + if (!fixedTimestep_ && adaptInfo_->timeErrorLow()) { + adaptInfo_->setTimestep(adaptInfo_->getTimestep() *time_delta_2); } } @@ -157,7 +157,7 @@ namespace AMDiS { { FUNCNAME("AdaptInstationary::oneTimestep"); - adaptInfo->setTimestepIteration(0); + adaptInfo_->setTimestepIteration(0); switch(strategy) { @@ -172,7 +172,7 @@ namespace AMDiS { explicitTimeStrategy(); } - adaptInfo->incTimestepNumber(); + adaptInfo_->incTimestepNumber(); } int AdaptInstationary::adapt() @@ -181,30 +181,29 @@ namespace AMDiS { int errorCode = 0; - TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep()) + TEST_EXIT(adaptInfo_->getTimestep() >= adaptInfo_->getMinTimestep()) ("timestep < min timestep\n"); - TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep()) + TEST_EXIT(adaptInfo_->getTimestep() <= adaptInfo_->getMaxTimestep()) ("timestep > max timestep\n"); - TEST_EXIT(adaptInfo->getTimestep() > 0)("timestep <= 0!\n"); + TEST_EXIT(adaptInfo_->getTimestep() > 0)("timestep <= 0!\n"); - if (adaptInfo->getTimestepNumber() == 0) { - adaptInfo->setTime(adaptInfo->getStartTime()); - initialAdaptInfo_->setStartTime(adaptInfo->getStartTime()); - initialAdaptInfo_->setTime(adaptInfo->getStartTime()); + if (adaptInfo_->getTimestepNumber() == 0) { + adaptInfo_->setTime(adaptInfo_->getStartTime()); + initialAdaptInfo_->setStartTime(adaptInfo_->getStartTime()); + initialAdaptInfo_->setTime(adaptInfo_->getStartTime()); - problemTime_->setTime(adaptInfo); + problemTime_->setTime(adaptInfo_); // initial adaption problemTime_->solveInitialProblem(initialAdaptInfo_); - problemTime_->transferInitialSolution(adaptInfo); + problemTime_->transferInitialSolution(adaptInfo_); } - // while (adaptInfo->getTime() < adaptInfo->getEndTime() - DBL_TOL) { - while (adaptInfo->getEndTime() - adaptInfo->getTime() > DBL_TOL) { + while (adaptInfo_->getTime() < adaptInfo_->getEndTime() - DBL_TOL) { iterationTimestamp_ = time(NULL); - problemTime_->initTimestep(adaptInfo); + problemTime_->initTimestep(adaptInfo_); #ifdef _OPENMP if (problemTime_->existsDelayedCalculation()) { @@ -224,9 +223,9 @@ namespace AMDiS { oneTimestep(); #endif - problemTime_->closeTimestep(adaptInfo); + problemTime_->closeTimestep(adaptInfo_); - if (breakWhenStable && (adaptInfo->getSolverIterations() == 0)) { + if (breakWhenStable && (adaptInfo_->getSolverIterations() == 0)) { break; } @@ -270,7 +269,7 @@ namespace AMDiS { FUNCNAME("AdaptInstationary::serialize()"); problemIteration_->serialize(out); - adaptInfo->serialize(out); + adaptInfo_->serialize(out); if (problemTime_) { problemTime_->serialize(out); } @@ -281,7 +280,7 @@ namespace AMDiS { FUNCNAME("AdaptInstationary::deserialize()"); problemIteration_->deserialize(in); - adaptInfo->deserialize(in); + adaptInfo_->deserialize(in); if (problemTime_) { problemTime_->deserialize(in); } @@ -299,20 +298,20 @@ namespace AMDiS { time_t currentTimestamp = time(NULL); // Update list with the last iteration runtimes. - lastIterationsDuration.push(currentTimestamp - iterationTimestamp_); + lastIterationsDuration_.push(currentTimestamp - iterationTimestamp_); // The list should not contain more than 5 elements. If so, delete the oldest one. - if (lastIterationsDuration.size() > 5) { - lastIterationsDuration.pop(); + if (lastIterationsDuration_.size() > 5) { + lastIterationsDuration_.pop(); } // Calculate the avarage of the last iterations. - ::std::queue<int> tmpQueue = lastIterationsDuration; + ::std::queue<int> tmpQueue = lastIterationsDuration_; int avrgLastIterations = 0; while (!tmpQueue.empty()) { avrgLastIterations += tmpQueue.front(); tmpQueue.pop(); } - avrgLastIterations /= lastIterationsDuration.size(); + avrgLastIterations /= lastIterationsDuration_.size(); // Check if there is enough time for a further iteration. if (initialTimestamp_ + queueRuntime_ - currentTimestamp < avrgLastIterations * 2) { diff --git a/AMDiS/src/AdaptInstationary.h b/AMDiS/src/AdaptInstationary.h index c0ed8235673405a79e038a3ecaac4c17c77dab80..0ca426ac36358dd011f80f97e4608f93f8b3b120 100644 --- a/AMDiS/src/AdaptInstationary.h +++ b/AMDiS/src/AdaptInstationary.h @@ -186,7 +186,7 @@ namespace AMDiS { /** \brief * Stores the runtime (in seconds) of some last timestep iterations. */ - ::std::queue<int> lastIterationsDuration; + ::std::queue<int> lastIterationsDuration_; }; } diff --git a/AMDiS/src/AdaptStationary.cc b/AMDiS/src/AdaptStationary.cc index b5265570007526a9bb60596e00a7f42c0b0fe63d..62a297d153258dd0d2e69217db19c6314a117669 100644 --- a/AMDiS/src/AdaptStationary.cc +++ b/AMDiS/src/AdaptStationary.cc @@ -20,26 +20,26 @@ namespace AMDiS { FUNCNAME("AdaptStationary::adapt()"); // initial iteration - if (adaptInfo->getSpaceIteration() == -1) { - problemIteration_->beginIteration(adaptInfo); - problemIteration_->oneIteration(adaptInfo, NO_ADAPTION); - problemIteration_->endIteration(adaptInfo); - adaptInfo->incSpaceIteration(); + if (adaptInfo_->getSpaceIteration() == -1) { + problemIteration_->beginIteration(adaptInfo_); + problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION); + problemIteration_->endIteration(adaptInfo_); + adaptInfo_->incSpaceIteration(); } // adaption loop - while (!adaptInfo->spaceToleranceReached() && - (adaptInfo->getSpaceIteration() < adaptInfo->getMaxSpaceIteration() || - adaptInfo->getMaxSpaceIteration() < 0) ) { + while (!adaptInfo_->spaceToleranceReached() && + (adaptInfo_->getSpaceIteration() < adaptInfo_->getMaxSpaceIteration() || + adaptInfo_->getMaxSpaceIteration() < 0) ) { - problemIteration_->beginIteration(adaptInfo); - Flag adapted = problemIteration_->oneIteration(adaptInfo, FULL_ITERATION); - problemIteration_->endIteration(adaptInfo); + problemIteration_->beginIteration(adaptInfo_); + Flag adapted = problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION); + problemIteration_->endIteration(adaptInfo_); if (!adapted) break; - adaptInfo->incSpaceIteration(); + adaptInfo_->incSpaceIteration(); } return 0; diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index 501265872158252cd4f3be4ad5669da7b100d97e..fb1e841098bf61ee9de10640e0d86b4aaaecf30a 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -785,24 +785,23 @@ namespace AMDiS { } template<typename T> - DOFVector<T>& DOFVector<T>::operator=(const DOFVector<T>& rhs) + DOFVector<T>& DOFVector<T>::operator=(const DOFVector<T>& rhs ) { - feSpace = rhs.feSpace; - vec = rhs.vec; - this->elementVector = NULL; - interFct = rhs.interFct; - refineInter = rhs.refineInter; - coarsenOperation = rhs.coarsenOperation; - this->operators = rhs.operators; - this->operatorFactor = rhs.operatorFactor; + feSpace=rhs.feSpace; + vec=rhs.vec; + this->elementVector=NULL; + interFct=rhs.interFct; + refineInter=rhs.refineInter; + coarsenOperation=rhs.coarsenOperation; + this->operators=rhs.operators; + this->operatorFactor=rhs.operatorFactor; if (rhs.boundaryManager) { - if (this->boundaryManager) - delete this->boundaryManager; + if(this->boundaryManager) delete this->boundaryManager; this->boundaryManager = new BoundaryManager(*rhs.boundaryManager); // boundaryManager->setDOFVector(this); - } else { - this->boundaryManager = NULL; } + else + this->boundaryManager=NULL; return *this; } diff --git a/AMDiS/src/DataCollector.h b/AMDiS/src/DataCollector.h index 0c91d07770c278bb855ec1f97694080704f1ba10..86d6cf5fca1f97db450c9aae20f0344c5e6f4887 100644 --- a/AMDiS/src/DataCollector.h +++ b/AMDiS/src/DataCollector.h @@ -137,6 +137,10 @@ namespace AMDiS { */ Mesh* getMesh(); + void setMesh(Mesh *mesh) { + mesh_ = mesh; + }; + protected: /** \brief * Start collecting element and vertex data of the problem. diff --git a/AMDiS/src/ElementFileWriter.cc b/AMDiS/src/ElementFileWriter.cc index 38e1533da89ea7d3c3370fcb3210ec2ea4f1a822..ba5717157f1daaebd95b2f69241a080f5d828070 100644 --- a/AMDiS/src/ElementFileWriter.cc +++ b/AMDiS/src/ElementFileWriter.cc @@ -36,10 +36,8 @@ namespace AMDiS { GET_PARAMETER(0, name + "->output->append index", "%d", &appendIndex); GET_PARAMETER(0, name + "->output->index length", "%d", &indexLength); GET_PARAMETER(0, name + "->output->index decimals", "%d", &indexDecimals); - GET_PARAMETER(0, name + "->output->write every i-th timestep", "%d", &tsModulo); - - TEST_EXIT(tsModulo > 0) - ("Init file option \"write every i-th timestep\" is smaller than 1!\n"); + GET_PARAMETER(0, name + "->output->write every i-th timestep", "%d", + &tsModulo); } void ElementFileWriter::writeFiles(AdaptInfo *adaptInfo, bool force, diff --git a/AMDiS/src/FileWriter.cc b/AMDiS/src/FileWriter.cc index 9e990aadcabcf1f7f0da256aeb917af04ae90f75..592292385f9430e75e0322dba14adcfbb0930459 100644 --- a/AMDiS/src/FileWriter.cc +++ b/AMDiS/src/FileWriter.cc @@ -155,9 +155,6 @@ namespace AMDiS { TEST_EXIT(!delayWriting_ || amdisHaveOpenMP) ("Delayed writing only possible with OpenMP support!\n"); - TEST_EXIT(tsModulo > 0) - ("Init file option \"write every i-th timestep\" is smaller than 1!\n"); - } void FileWriter::writeFiles(AdaptInfo *adaptInfo, diff --git a/AMDiS/src/MeshStructure.cc b/AMDiS/src/MeshStructure.cc index eb432902ea489f5ec061d99003a23e613ab2a970..cb79462554e55748ac28468c93b04e0c929a56a3 100644 --- a/AMDiS/src/MeshStructure.cc +++ b/AMDiS/src/MeshStructure.cc @@ -142,12 +142,12 @@ namespace AMDiS { reset(); elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); while (elInfo) { - TEST_EXIT_DBG(cont)("unexpected structure code end!\n"); + TEST_EXIT(cont)("unexpected structure code end!\n"); Element *element = elInfo->getElement(); if (isLeafElement()) { - TEST_EXIT_DBG(element->isLeaf())("mesh finer than code\n"); + TEST_EXIT(element->isLeaf())("mesh finer than code\n"); }; if (element->isLeaf() && !isLeafElement()) { @@ -159,7 +159,7 @@ namespace AMDiS { if (checkPartition) { PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> (element->getElementData(PARTITION_ED)); - TEST_EXIT_DBG(partitionData)("no partition element data\n"); + TEST_EXIT(partitionData)("no partition element data\n"); PartitionStatus status = partitionData->getPartitionStatus(); if ((debugMode == false) && (status == OUT || status == UNDEFINED)) { decorate = false; diff --git a/AMDiS/src/ParMetisPartitioner.cc b/AMDiS/src/ParMetisPartitioner.cc index d5da44333ca1fc47379402a7086d42bb936299b8..5381ca913cb3e496f95a705b2a433f7154931a69 100644 --- a/AMDiS/src/ParMetisPartitioner.cc +++ b/AMDiS/src/ParMetisPartitioner.cc @@ -12,12 +12,13 @@ namespace AMDiS { - ParMetisMesh::ParMetisMesh(Mesh *mesh) - : numElements_(0) + ParMetisMesh::ParMetisMesh(Mesh *mesh, MPI::Comm *comm) + : numElements_(0), + mpiComm(comm) { FUNCNAME("ParMetisMesh::ParMetisMesh()"); - int i; - int mpiSize = MPI::COMM_WORLD.Get_size(); + + int mpiSize = mpiComm->Get_size(); int nodeCounter = 0; int elementCounter = 0; @@ -28,17 +29,16 @@ namespace AMDiS { TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); // get partition data PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> (element->getElementData(PARTITION_ED)); - if(partitionData && - partitionData->getPartitionStatus() == IN && - partitionData->getLevel() == 0) - { + if (partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) { elementCounter++; } @@ -56,7 +56,7 @@ namespace AMDiS { elem_p2a_ = GET_MEMORY(int, numElements_); - if(dim_ == dow) { + if (dim_ == dow) { xyz_ = GET_MEMORY(float, numElements_ * dim_); } else { xyz_ = NULL; @@ -69,10 +69,10 @@ namespace AMDiS { float *ptr_xyz = xyz_; // gather element numbers and create elmdist - MPI::COMM_WORLD.Allgather(&numElements_, 1, MPI_INT, - elmdist_ + 1, 1, MPI_INT); + mpiComm->Allgather(&numElements_, 1, MPI_INT, elmdist_ + 1, 1, MPI_INT); + elmdist_[0] = 0; - for(i = 2; i < mpiSize + 1; i++) { + for (int i = 2; i < mpiSize + 1; i++) { elmdist_[i] += elmdist_[i - 1]; } @@ -85,7 +85,7 @@ namespace AMDiS { elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_COORDS); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); int index = element->getIndex(); @@ -94,10 +94,9 @@ namespace AMDiS { (element->getElementData(PARTITION_ED)); // if element in partition - if(partitionData && - partitionData->getPartitionStatus() == IN && - partitionData->getLevel() == 0) - { + if (partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) { // remember index setParMetisIndex(index, elementCounter); setAMDiSIndex(elementCounter, index); @@ -108,15 +107,15 @@ namespace AMDiS { ptr_eptr++; // write eind entries (element nodes) - for(i = 0; i < dim_ + 1; i++) { + for (int i = 0; i < dim_ + 1; i++) { *ptr_eind = element->getDOF(i, 0); ptr_eind++; } // write xyz element coordinates - if(ptr_xyz) { + if (ptr_xyz) { elInfo->coordToWorld(bary, &world); - for(i = 0; i < dim_; i++) { + for (int i = 0; i < dim_; i++) { *ptr_xyz = static_cast<float>(world[i]); ptr_xyz++; } @@ -130,22 +129,33 @@ namespace AMDiS { ParMetisMesh::~ParMetisMesh() { - if(eptr_) FREE_MEMORY(eptr_, int, numElements_ + 1); - if(eind_) FREE_MEMORY(eind_, int, numElements_ * (dim_ + 1)); - if(elmdist_) FREE_MEMORY(elmdist_, int, MPI::COMM_WORLD.Get_size() + 1); - if(xyz_) FREE_MEMORY(xyz_, float, numElements_ * dim_); - if(elem_p2a_) FREE_MEMORY(elem_p2a_, int, numElements_); + if (eptr_) + FREE_MEMORY(eptr_, int, numElements_ + 1); + + if (eind_) + FREE_MEMORY(eind_, int, numElements_ * (dim_ + 1)); + + if (elmdist_) + FREE_MEMORY(elmdist_, int, mpiComm->Get_size() + 1); + + if (xyz_) + FREE_MEMORY(xyz_, float, numElements_ * dim_); + + if (elem_p2a_) + FREE_MEMORY(elem_p2a_, int, numElements_); } ParMetisGraph::ParMetisGraph(ParMetisMesh *parMetisMesh, + MPI::Comm *comm, int ncommonnodes) : parMetisMesh_(parMetisMesh) { int numflag = 0; - if(ncommonnodes == -1) ncommonnodes = parMetisMesh->getDim(); + if (ncommonnodes == -1) + ncommonnodes = parMetisMesh->getDim(); - MPI_Comm comm = MPI_COMM_WORLD; + MPI_Comm tmpComm = MPI_Comm(*comm); ParMETIS_V3_Mesh2Dual(parMetisMesh_->getElementDist(), parMetisMesh_->getElementPtr(), @@ -154,23 +164,22 @@ namespace AMDiS { &ncommonnodes, &xadj_, &adjncy_, - &comm); + &tmpComm); } ParMetisGraph::~ParMetisGraph() { free(xadj_); free(adjncy_); -// if(xadj_) delete [] xadj_; -// if(adjncy_) delete [] adjncy_; } + void ParMetisPartitioner::deletePartitionData() { TraverseStack stack; ElInfo *elInfo; elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); element->deleteElementData(PARTITION_ED); elInfo = stack.traverseNext(elInfo); @@ -178,8 +187,8 @@ namespace AMDiS { } void ParMetisPartitioner::createPartitionData() { - int mpiRank = MPI::COMM_WORLD.Get_rank(); - int mpiSize = MPI::COMM_WORLD.Get_size(); + int mpiRank = mpiComm->Get_rank(); + int mpiSize = mpiComm->Get_size(); TraverseStack stack; ElInfo *elInfo; @@ -187,7 +196,7 @@ namespace AMDiS { // === create initial partitioning on AMDiS mesh === int totalElementCounter = 0; elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); //int index = element->getIndex(); @@ -198,7 +207,7 @@ namespace AMDiS { NEW PartitionElementData(element->getElementData()); element->setElementData(elData); - if(totalElementCounter % mpiSize == mpiRank) { + if (totalElementCounter % mpiSize == mpiRank) { elData->setPartitionStatus(IN); } else { elData->setPartitionStatus(UNDEFINED); @@ -207,61 +216,21 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - -// elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); -// while(elInfo) { -// Element *element = elInfo->getElement(); -// int index = element->getIndex(); - -// TEST_EXIT(element->getElementData(PARTITION_ED) == NULL) -// ("mesh already partitioned\n"); - -// PartitionElementData *elData = -// NEW PartitionElementData(element->getElementData()); -// element->setElementData(elData); -// elData->setPartitionStatus(UNDEFINED); -// elData->setLevel(0); -// elInfo = stack.traverseNext(elInfo); -// } } void ParMetisPartitioner::partition(std::map<int, double> *elemWeights, PartitionMode mode, float itr) { - int mpiSize = MPI::COMM_WORLD.Get_size(); + int mpiSize = mpiComm->Get_size(); TraverseStack stack; ElInfo *elInfo; - // === create initial partitioning on AMDiS mesh === - -// if(mode == INITIAL) { -// int totalElementCounter = 0; -// elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); -// while(elInfo) { -// Element *element = elInfo->getElement(); -// int index = element->getIndex(); - -// // get partition data -// PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> -// (element->getElementData(PARTITION_ED)); - -// if(partitionData && partitionData->getLevel() == 0) { -// if(totalElementCounter % mpiSize == mpiRank) { -// partitionData->setPartitionStatus(IN); -// } else { -// partitionData->setPartitionStatus(UNDEFINED); -// } -// totalElementCounter++; -// } -// elInfo = stack.traverseNext(elInfo); -// } -// } - // === create parmetis mesh === - if(parMetisMesh_) DELETE parMetisMesh_; - parMetisMesh_ = NEW ParMetisMesh(mesh_); + if (parMetisMesh_) + DELETE parMetisMesh_; + parMetisMesh_ = NEW ParMetisMesh(mesh_, mpiComm); int numElements = parMetisMesh_->getNumElements(); @@ -271,20 +240,18 @@ namespace AMDiS { float maxWgt = 0.0; float *ptr_floatWgts = floatWgts; - //int *ptr_wgts = wgts; elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); // get partition data PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> (element->getElementData(PARTITION_ED)); - if(partitionData && - partitionData->getPartitionStatus() == IN && - partitionData->getLevel() == 0) - { + if (partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) { int index = element->getIndex(); // get weight @@ -299,23 +266,15 @@ namespace AMDiS { } float tmp; - MPI::COMM_WORLD.Allreduce(&maxWgt, - &tmp, - 1, - MPI_FLOAT, - MPI_MAX); + mpiComm->Allreduce(&maxWgt, &tmp, 1, MPI_FLOAT, MPI_MAX); maxWgt = tmp; // === create dual graph === - ParMetisGraph parMetisGraph(parMetisMesh_); + ParMetisGraph parMetisGraph(parMetisMesh_, mpiComm); // === partitioning of dual graph === - MPI_Comm comm = MPI_COMM_WORLD; - - int i; int wgtflag = elemWeights ? 2 : 0; // weights at vertices only! int numflag = 0; // c numbering style! - //int ndims = mesh_->getDim(); int ncon = elemWeights ? 1 : 0; // one weight at each vertex! int nparts = mpiSize; // number of partitions float *tpwgts = elemWeights ? GET_MEMORY(float, mpiSize) : NULL; @@ -324,39 +283,23 @@ namespace AMDiS { int edgecut = -1; int *part = GET_MEMORY(int, numElements); - if(elemWeights) { - for(i = 0; i < mpiSize; i++) { + if (elemWeights) { + for (int i = 0; i < mpiSize; i++) { // set tpwgts - tpwgts[i] = 1.0/nparts; + tpwgts[i] = 1.0 / nparts; } float scale = 10000 / maxWgt; - for(i = 0; i < numElements; i++) { + for (int i = 0; i < numElements; i++) { // scale wgts wgts[i] = static_cast<int>(floatWgts[i] * scale); } } + MPI_Comm tmpComm = MPI_Comm(*mpiComm); + switch(mode) { case INITIAL: -// if(parMetisMesh_->getXYZ()) { -// ParMETIS_V3_PartGeomKway(parMetisMesh_->getElementDist(), -// parMetisGraph.getXAdj(), -// parMetisGraph.getAdjncy(), -// wgts, -// NULL, -// &wgtflag, -// &numflag, -// &ndims, -// parMetisMesh_->getXYZ(), -// &ncon, -// &nparts, -// tpwgts, -// &ubvec, -// options, -// &edgecut, -// part, -// &comm); ParMETIS_V3_PartKway(parMetisMesh_->getElementDist(), parMetisGraph.getXAdj(), parMetisGraph.getAdjncy(), @@ -371,15 +314,12 @@ namespace AMDiS { options, &edgecut, part, - &comm); -// } else { -// ERROR_EXIT("not yet dim != dow (no xyz)\n"); -// } + &tmpComm); break; case ADAPTIVE_REPART: { int *vsize = GET_MEMORY(int, numElements); - for(i = 0; i < numElements; i++) { + for (int i = 0; i < numElements; i++) { vsize[i] = 1; } ParMETIS_V3_AdaptiveRepart(parMetisMesh_->getElementDist(), @@ -398,7 +338,7 @@ namespace AMDiS { options, &edgecut, part, - &comm); + &tmpComm); FREE_MEMORY(vsize, int, numElements); } break; @@ -417,7 +357,7 @@ namespace AMDiS { options, &edgecut, part, - &comm); + &tmpComm); break; default: ERROR_EXIT("unknown partitioning mode\n"); @@ -426,9 +366,12 @@ namespace AMDiS { // === distribute new partition data === distributePartitioning(part); - if(floatWgts) FREE_MEMORY(floatWgts, float, numElements); - if(wgts) FREE_MEMORY(wgts, int, numElements); - if(tpwgts) FREE_MEMORY(tpwgts, float, mpiSize); + if (floatWgts) + FREE_MEMORY(floatWgts, float, numElements); + if (wgts) + FREE_MEMORY(wgts, int, numElements); + if (tpwgts) + FREE_MEMORY(tpwgts, float, mpiSize); FREE_MEMORY(part, int, numElements); } @@ -439,43 +382,38 @@ namespace AMDiS { partitionVec->clear(); // update ParMETIS mesh to new partitioning - if(!parMetisMesh_) parMetisMesh_ = NEW ParMetisMesh(mesh_); + if (!parMetisMesh_) + parMetisMesh_ = NEW ParMetisMesh(mesh_, mpiComm); - int i, j; - //int dim = mesh_->getDim(); - int mpiRank = MPI::COMM_WORLD.Get_rank(); - int mpiSize = MPI::COMM_WORLD.Get_size(); + int mpiRank = mpiComm->Get_rank(); + int mpiSize = mpiComm->Get_size(); int *numPartitionElements = GET_MEMORY(int, mpiSize); int *elmdist = parMetisMesh_->getElementDist(); - for(i = 0; i < mpiSize; i++) { + for (int i = 0; i < mpiSize; i++) { numPartitionElements[i] = elmdist[i+1] - elmdist[i]; } // === count number of elements === int numElements = 0; int localElements = parMetisMesh_->getNumElements(); - MPI::COMM_WORLD.Allreduce(&localElements, - &numElements, - 1, - MPI_INT, - MPI_SUM); + mpiComm->Allreduce(&localElements, &numElements, 1, MPI_INT, MPI_SUM); int *partitionElements = GET_MEMORY(int, numElements); // distribute partition elements - MPI::COMM_WORLD.Allgatherv(parMetisMesh_->getAMDiSIndices(), - numPartitionElements[mpiRank], - MPI_INT, - partitionElements, - numPartitionElements, - elmdist, - MPI_INT); + mpiComm->Allgatherv(parMetisMesh_->getAMDiSIndices(), + numPartitionElements[mpiRank], + MPI_INT, + partitionElements, + numPartitionElements, + elmdist, + MPI_INT); // fill partitionVec - for(i = 0; i < mpiSize; i++) { - for(j = 0; j < numPartitionElements[i]; j++) { + for (int i = 0; i < mpiSize; i++) { + for (int j = 0; j < numPartitionElements[i]; j++) { (*partitionVec)[partitionElements[elmdist[i] + j]] = i; } } @@ -486,50 +424,45 @@ namespace AMDiS { void ParMetisPartitioner::distributePartitioning(int *part) { - int i; - int mpiSize = MPI::COMM_WORLD.Get_size(); - int mpiRank = MPI::COMM_WORLD.Get_rank(); - + int mpiSize = mpiComm->Get_size(); + int mpiRank = mpiComm->Get_rank(); int numElements = parMetisMesh_->getNumElements(); // count elements per partition in this rank int *numPartitionElements = GET_MEMORY(int, mpiSize); - for(i = 0; i < mpiSize; i++) + for (int i = 0; i < mpiSize; i++) numPartitionElements[i] = 0; - for(i = 0; i < numElements; i++) { + for (int i = 0; i < numElements; i++) { numPartitionElements[part[i]]++; } // collect number of partition elements from all ranks for this rank int *numRankElements = GET_MEMORY(int, mpiSize); - MPI::COMM_WORLD.Alltoall(numPartitionElements, 1, MPI_INT, - numRankElements, 1, MPI_INT); + mpiComm->Alltoall(numPartitionElements, 1, MPI_INT, + numRankElements, 1, MPI_INT); // sum up partition elements over all ranks int *sumPartitionElements = GET_MEMORY(int, mpiSize); - MPI::COMM_WORLD.Allreduce(numPartitionElements, - sumPartitionElements, - mpiSize, - MPI_INT, - MPI_SUM); + mpiComm->Allreduce(numPartitionElements, sumPartitionElements, mpiSize, + MPI_INT, MPI_SUM); // prepare distribution (fill partitionElements with AMDiS indices) int *bufferOffset = GET_MEMORY(int, mpiSize); bufferOffset[0] = 0; - for(i = 1; i < mpiSize; i++) { + for (int i = 1; i < mpiSize; i++) { bufferOffset[i] = bufferOffset[i - 1] + numPartitionElements[i - 1]; } int *partitionElements = GET_MEMORY(int, numElements); int **partitionPtr = GET_MEMORY(int*, mpiSize); - for(i = 0; i < mpiSize; i++) { + for (int i = 0; i < mpiSize; i++) { partitionPtr[i] = partitionElements + bufferOffset[i]; } - for(i = 0; i < numElements; i++) { + for (int i = 0; i < numElements; i++) { int partition = part[i]; int amdisIndex = parMetisMesh_->getAMDiSIndex(i); *(partitionPtr[partition]) = amdisIndex; @@ -540,45 +473,44 @@ namespace AMDiS { int *rankElements = GET_MEMORY(int, sumPartitionElements[mpiRank]); int *recvBufferOffset = GET_MEMORY(int, mpiSize); recvBufferOffset[0] = 0; - for(i = 1; i < mpiSize; i++) { + for (int i = 1; i < mpiSize; i++) { recvBufferOffset[i] = recvBufferOffset[i - 1] + numRankElements[i - 1]; } - MPI::COMM_WORLD.Alltoallv(partitionElements, - numPartitionElements, - bufferOffset, - MPI_INT, - rankElements, - numRankElements, - recvBufferOffset, - MPI_INT); + mpiComm->Alltoallv(partitionElements, + numPartitionElements, + bufferOffset, + MPI_INT, + rankElements, + numRankElements, + recvBufferOffset, + MPI_INT); // === partition AMDiS mesh === // write data in stl map std::map<int, bool> elementInPartition; - for(i = 0; i < mpiSize; i++) { - int *rankPtr; + for (int i = 0; i < mpiSize; i++) { int *rankStart = rankElements + recvBufferOffset[i]; int *rankEnd = rankStart + numRankElements[i]; - for(rankPtr = rankStart; rankPtr < rankEnd; ++rankPtr) { + for (int *rankPtr = rankStart; rankPtr < rankEnd; ++rankPtr) { elementInPartition[*rankPtr] = true; } } TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); // get partition data PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> (element->getElementData(PARTITION_ED)); - if(partitionData && partitionData->getLevel() == 0) { + if (partitionData && partitionData->getLevel() == 0) { int amdisIndex = element->getIndex(); - if(elementInPartition[amdisIndex]) { + if (elementInPartition[amdisIndex]) { partitionData->setPartitionStatus(IN); } else { partitionData->setPartitionStatus(OUT); @@ -591,10 +523,6 @@ namespace AMDiS { DELETE parMetisMesh_; parMetisMesh_ = NULL; - //parMetisMesh_ = NEW ParMetisMesh(mesh_); - -// MSG("rank %d partition elements: %d\n", -// mpiRank, sumPartitionElements[mpiRank]); FREE_MEMORY(rankElements, int, sumPartitionElements[mpiRank]); FREE_MEMORY(numPartitionElements, int, mpiSize); @@ -608,7 +536,7 @@ namespace AMDiS { void ParMetisPartitioner::descendPartitionData(Element *element) { - if(!element->isLeaf()) { + if (!element->isLeaf()) { Element *child0 = element->getChild(0); Element *child1 = element->getChild(1); @@ -637,12 +565,12 @@ namespace AMDiS { int partition = -1; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> (element->getElementData(PARTITION_ED)); - if(partitionData) { - if(partitionData->getLevel() == 0) { + if (partitionData) { + if (partitionData->getLevel() == 0) { partition = (*(coarseVec))[element->getIndex()]; } if(element->isLeaf()) { diff --git a/AMDiS/src/ParMetisPartitioner.h b/AMDiS/src/ParMetisPartitioner.h index 194f0b6549ca08f21ba18356bc169e37d332dc35..b5633721e1b89816e3ddc2c44eb3ce8bd34f261a 100644 --- a/AMDiS/src/ParMetisPartitioner.h +++ b/AMDiS/src/ParMetisPartitioner.h @@ -46,7 +46,7 @@ namespace AMDiS { public: MEMORY_MANAGED(ParMetisMesh); - ParMetisMesh(Mesh *mesh); + ParMetisMesh(Mesh *mesh, MPI::Comm *comm); ~ParMetisMesh(); @@ -98,23 +98,35 @@ namespace AMDiS { protected: int *eptr_; + int *eind_; + int *elmdist_; + int dim_; + float *xyz_; int numElements_; std::map<int, int> elem_a2p_; + int *elem_p2a_; + + /** \brief + * The MPI communicator that should be used for mesh partition. + */ + MPI::Comm *mpiComm; }; + class ParMetisGraph { public: MEMORY_MANAGED(ParMetisGraph); ParMetisGraph(ParMetisMesh *parMetisMesh, + MPI::Comm *comm, int ncommonnodes = -1); ~ParMetisGraph(); @@ -134,11 +146,13 @@ namespace AMDiS { int *adjncy_; }; + class ParMetisPartitioner { public: - ParMetisPartitioner(Mesh *mesh) + ParMetisPartitioner(Mesh *mesh, MPI::Comm *comm) : mesh_(mesh), + mpiComm(comm), parMetisMesh_(NULL) {}; @@ -162,6 +176,9 @@ namespace AMDiS { protected: Mesh *mesh_; + + MPI::Comm *mpiComm; + ParMetisMesh *parMetisMesh_; }; } diff --git a/AMDiS/src/ParallelProblem.cc b/AMDiS/src/ParallelProblem.cc index 39811f5aebc5f58b24cb3183c2b7dc97f1cc1518..9665ab5432be19474eda226ad0c94ca0d924f9b0 100644 --- a/AMDiS/src/ParallelProblem.cc +++ b/AMDiS/src/ParallelProblem.cc @@ -9,6 +9,7 @@ #include "Traverse.h" #include "ElInfo.h" #include "Element.h" +#include "MacroElement.h" #include "PartitionElementData.h" #include "ParMetisPartitioner.h" #include "Mesh.h" @@ -23,8 +24,10 @@ #include "MacroWriter.h" #include "ValueWriter.h" #include "SystemVector.h" +#include "VtkWriter.h" #include "mpi.h" #include <queue> +#include <time.h> namespace AMDiS { @@ -39,17 +42,6 @@ namespace AMDiS { } } - bool elementInPartitionDbg(ElInfo *elInfo) - { - // In debug mode, the first partition has to write the whole domain. - if (MPI::COMM_WORLD.Get_rank() == 0) { - return true; - } - - return elementInPartition(elInfo); - } - - class MyDualTraverse : public DualTraverse { public: @@ -61,8 +53,8 @@ namespace AMDiS { { PartitionElementData *elementData = dynamic_cast<PartitionElementData*> (elInfo->getElement()->getElementData(PARTITION_ED)); - if(elementData) { - if(elInfo->getElement()->isLeaf() && + if (elementData) { + if (elInfo->getElement()->isLeaf() && elementData->getLevel() < coarseLevel_) return false; if(elementData->getLevel() == coarseLevel_) @@ -78,15 +70,98 @@ namespace AMDiS { // ===== class ParallelProblemBase ========================================= // ========================================================================= - ParallelProblemBase::ParallelProblemBase(ProblemIterationInterface *iterationIF, + ParallelProblemBase::ParallelProblemBase(const std::string& name, + ProblemIterationInterface *iterationIF, ProblemTimeInterface *timeIF) : iterationIF_(iterationIF), - timeIF_(timeIF) + timeIF_(timeIF), + debugMode(0) { mpiRank = MPI::COMM_WORLD.Get_rank(); mpiSize = MPI::COMM_WORLD.Get_size(); + + GET_PARAMETER(0, name + "->debug mode", "%d", &debugMode); + + if (debugMode) { + MPI::Group group = MPI::COMM_WORLD.Get_group(); + + int rankSize = mpiSize - 1; + int *ranks = GET_MEMORY(int, rankSize); + for (int i = 0; i < rankSize; i++) { + ranks[i] = i + 1; + } + + amdisGroup = group.Incl(rankSize, ranks); + + mpiComm = MPI::COMM_WORLD.Create(amdisGroup); + + if (mpiComm != MPI::COMM_NULL) { + mpiRank = mpiComm.Get_rank(); + mpiSize = mpiComm.Get_size(); + debugServerProcess = false; + } else { + debugServerProcess = true; + } + + FREE_MEMORY(ranks, int, rankSize); + } else { + mpiComm = MPI::COMM_WORLD; + } } + void ParallelProblemBase::exitParallelization(AdaptInfo *adaptInfo) + { + if (!timeIF_) + closeTimestep(adaptInfo); + + amdisGroup.Free(); + }; + + Flag ParallelProblemBase::oneIteration(AdaptInfo *adaptInfo, Flag toDo) + { + Flag flag; + + if (mpiSize > 1 && toDo.isSet(MARK | ADAPT)) { + flag = iterationIF_->oneIteration(adaptInfo, MARK | ADAPT); + + double localWeightSum = setElemWeights(adaptInfo); + if (doPartitioning(adaptInfo, localWeightSum)) { + clock_t partitioningStart = clock(); + + synchronizeMeshes(adaptInfo); + partitionMesh(adaptInfo); + refineOverlap(adaptInfo); + createOverlap(adaptInfo); + synchronizeMeshes(adaptInfo); + exchangeDOFVectors(adaptInfo); + coarsenOutOfPartition(adaptInfo); + + clock_t partitioningEnd = clock(); + partitioningTime = TIME_USED(partitioningStart, + partitioningEnd); + computationStart = partitioningEnd; + } + + flag |= iterationIF_->oneIteration(adaptInfo, toDo & ~(MARK | ADAPT)); + } else { + flag = iterationIF_->oneIteration(adaptInfo, toDo); + } + + // synchronize adaption flag + unsigned long *flagBuffer = GET_MEMORY(unsigned long, mpiSize); + + unsigned long localFlag = flag.getFlags(); + + mpiComm.Allgather(&localFlag, 1, MPI_UNSIGNED_LONG, + flagBuffer, 1, MPI_UNSIGNED_LONG); + for (int i = 0; i < mpiSize; i++) { + flag.setFlag(flagBuffer[i]); + } + FREE_MEMORY(flagBuffer, unsigned long, mpiSize); + + return flag; + }; + // ========================================================================= // ===== class ParallelProblem ============================================= // ========================================================================= @@ -98,7 +173,7 @@ namespace AMDiS { Mesh *mesh, RefinementManager *rm, CoarseningManager *cm) - : ParallelProblemBase(iterationIF, timeIF), + : ParallelProblemBase(name, iterationIF, timeIF), name_(name), mesh(mesh), refinementManager(rm), @@ -114,8 +189,7 @@ namespace AMDiS { adaptiveThresholds_(0), thresholdIncFactor_(2.0), thresholdDecFactor_(0.5), - repartTimeFactor_(10.0), - debugMode(0) + repartTimeFactor_(10.0) { GET_PARAMETER(0, name_ + "->upper part threshold", "%f", &upperPartThreshold_); @@ -132,7 +206,7 @@ namespace AMDiS { TEST_EXIT(localCoarseGridLevel_ >= globalCoarseGridLevel_) ("local coarse grid level < global coarse grid level\n"); - partitioner_ = NEW ParMetisPartitioner(mesh); + partitioner_ = NEW ParMetisPartitioner(mesh, &mpiComm); GET_PARAMETER(0, name_ + "->adaptive thresholds", "%d", &adaptiveThresholds_); @@ -153,21 +227,11 @@ namespace AMDiS { } minUpperTH_ = upperPartThreshold_; maxLowerTH_ = lowerPartThreshold_; - - GET_PARAMETER(0, name_ + "->debug mode", "%d", &debugMode); - - if (debugMode) { - dbgMesh = NEW Mesh(mesh->getName(), mesh->getDim()); - } } ParallelProblem::~ParallelProblem() { DELETE partitioner_; - - if (debugMode) { - DELETE dbgMesh; - } } bool ParallelProblem::doPartitioning(AdaptInfo *adaptInfo, double localWeightSum) @@ -178,8 +242,8 @@ namespace AMDiS { int *partArray = GET_MEMORY(int, mpiSize); int part = 0; - MPI::COMM_WORLD.Gather(&localWeightSum, 1, MPI_DOUBLE, - weightSum, 1, MPI_DOUBLE, 0); + mpiComm.Gather(&localWeightSum, 1, MPI_DOUBLE, + weightSum, 1, MPI_DOUBLE, 0); if (mpiRank == 0) { @@ -230,8 +294,8 @@ namespace AMDiS { } } - MPI::COMM_WORLD.Scatter(partArray, 1, MPI_INT, - &part, 1, MPI_INT, 0); + mpiComm.Scatter(partArray, 1, MPI_INT, + &part, 1, MPI_INT, 0); FREE_MEMORY(weightSum, double, mpiSize); FREE_MEMORY(partArray, int, mpiSize); @@ -246,49 +310,53 @@ namespace AMDiS { void ParallelProblem::partitionMesh(AdaptInfo *adaptInfo) { static bool initial = true; - if(initial) { + if (initial) { initial = false; - partitioner_->fillCoarsePartitionVec(&oldPartitionVec_); + partitioner_->fillCoarsePartitionVec(&oldPartitionVec); partitioner_->partition(&elemWeights_, INITIAL); } else { - oldPartitionVec_ = partitionVec_; + oldPartitionVec = partitionVec; partitioner_->partition(&elemWeights_, ADAPTIVE_REPART, 100.0 /*0.000001*/); } - partitioner_->fillCoarsePartitionVec(&partitionVec_); + partitioner_->fillCoarsePartitionVec(&partitionVec); } void ParallelProblem::refineOverlap(AdaptInfo *adaptInfo) { - int i, dim = mesh->getDim(); + int dim = mesh->getDim(); bool finished = (localCoarseGridLevel_ == 0); //for(j = globalCoarseGridLevel_; j < localCoarseGridLevel_; j++) { - while(!finished) { + while (!finished) { std::map<DegreeOfFreedom, int> inOut; // 1: in, 2: out, 3: border dof // mark in/out/border dofs TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); const DegreeOfFreedom **dofs = element->getDOF(); - if(partitionData->getPartitionStatus() == IN) { - for(i = 0; i < dim + 1; i++) { + if (partitionData->getPartitionStatus() == IN) { + for (int i = 0; i < dim + 1; i++) { DegreeOfFreedom dof = dofs[i][0]; - if(inOut[dof] == 2) inOut[dof] = 3; - if(inOut[dof] == 0) inOut[dof] = 1; + if (inOut[dof] == 2) + inOut[dof] = 3; + if (inOut[dof] == 0) + inOut[dof] = 1; } } else { - for(i = 0; i < dim + 1; i++) { + for (int i = 0; i < dim + 1; i++) { DegreeOfFreedom dof = dofs[i][0]; - if(inOut[dof] == 1) inOut[dof] = 3; - if(inOut[dof] == 0) inOut[dof] = 2; + if (inOut[dof] == 1) + inOut[dof] = 3; + if (inOut[dof] == 0) + inOut[dof] = 2; } } @@ -299,35 +367,38 @@ namespace AMDiS { finished = true; bool marked = false; elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); int level = partitionData->getLevel(); - if(level < localCoarseGridLevel_) { - if(partitionData->getPartitionStatus() != IN) { + if (level < localCoarseGridLevel_) { + if (partitionData->getPartitionStatus() != IN) { const DegreeOfFreedom **dofs = element->getDOF(); - for(i = 0; i < dim + 1; i++) { + for (int i = 0; i < dim + 1; i++) { DegreeOfFreedom dof = dofs[i][0]; - if(inOut[dof] == 3) { + if (inOut[dof] == 3) { element->setMark(1); marked = true; - if((level + 1) < localCoarseGridLevel_) finished = false; + if ((level + 1) < localCoarseGridLevel_) + finished = false; break; } } } else { element->setMark(1); marked = true; - if((level + 1) < localCoarseGridLevel_) finished = false; + if ((level + 1) < localCoarseGridLevel_) + finished = false; } } elInfo = stack.traverseNext(elInfo); } - if(marked) refinementManager->refineMesh(mesh); + if (marked) + refinementManager->refineMesh(mesh); } } @@ -335,7 +406,7 @@ namespace AMDiS { { TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); - while(elInfo) { + while (elInfo) { PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); int refinements = globalCoarseGridLevel_ - partitionData->getLevel(); @@ -366,7 +437,7 @@ namespace AMDiS { } meshCoarsened = coarseningManager->coarsenMesh(mesh); } - MPI::COMM_WORLD.Barrier(); + mpiComm.Barrier(); } void ParallelProblem::exchangeMeshStructureCodes(MeshStructure *structures) @@ -378,15 +449,20 @@ namespace AMDiS { // broadcast code sizes int *codeSize = GET_MEMORY(int, mpiSize); int tmp = static_cast<int>(myCode.size()); + mpiComm.Allgather(&tmp, 1, MPI_INT, codeSize, 1, MPI_INT); + if (debugMode) { + // send code sizes also to debug server + MPI::COMM_WORLD.Gather(&tmp, 1, MPI_INT, NULL, 1, MPI_INT, 0); + } - MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, - codeSize, 1, MPI_INT); - // broadcast number of elements int *elements = GET_MEMORY(int, mpiSize); tmp = structures[mpiRank].getNumElements(); - MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, - elements, 1, MPI_INT); + mpiComm.Allgather(&tmp, 1, MPI_INT, elements, 1, MPI_INT); + if (debugMode) { + // send number of elements also to debug server + MPI::COMM_WORLD.Gather(&tmp, 1, MPI_INT, NULL, 1, MPI_INT, 0); + } // broadcast codes int *codeOffset = GET_MEMORY(int, mpiSize); @@ -397,22 +473,25 @@ namespace AMDiS { } unsigned long int *code = GET_MEMORY(unsigned long int, codeSizeSum); - unsigned long int *localCode = GET_MEMORY(unsigned long int, codeSize[mpiRank]); - + unsigned long int *localCode = GET_MEMORY(unsigned long int, codeSize[mpiRank]); unsigned long int *ptr; std::vector<unsigned long int>::const_iterator it, end = myCode.end(); for (ptr = localCode, it = myCode.begin(); it != end; - ++it, ++ptr) - { + ++it, ++ptr) { *ptr = *it; } - - MPI::COMM_WORLD.Allgatherv(localCode, codeSize[mpiRank], - MPI_UNSIGNED_LONG, - code, codeSize, codeOffset, - MPI_UNSIGNED_LONG); + + mpiComm.Allgatherv(localCode, codeSize[mpiRank], + MPI_UNSIGNED_LONG, + code, codeSize, codeOffset, + MPI_UNSIGNED_LONG); + if (debugMode) { + // send codes also to debug server + MPI::COMM_WORLD.Send(localCode, codeSize[mpiRank], + MPI_UNSIGNED_LONG, 0, 100); + } for (int rank = 0; rank < mpiSize; rank++) { if (rank != mpiRank) { @@ -457,16 +536,6 @@ namespace AMDiS { refinementManager, true); - // In debug mode, process 0 builds the global solution mesh. - if (debugMode) { - dbgMesh = mesh; - if (mpiRank == 0) { - structures[mpiRank].fitMeshToStructure(dbgMesh, - refinementManager, - true, true); - } - } - DELETE [] structures; } @@ -490,20 +559,16 @@ namespace AMDiS { { FUNCNAME("ParallelProblem::exchangeRankSolutions()"); - int level = localCoarseGridLevel_, overlap = 1; - bool openOverlap = true; - ParallelProblem::fillVertexPartitions(level, overlap, openOverlap, - overlapDistance_); + ParallelProblem::fillVertexPartitions(localCoarseGridLevel_, 1, true, overlapDistance_); overlapDistance_.clear(); - const FiniteElemSpace *feSpace = rankSolutions[0]->getFESpace(); int dim = workMesh->getDim(); const BasisFunction *basFcts = feSpace->getBasisFcts(); int numFcts = basFcts->getNumber(); DegreeOfFreedom *coarseDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); DegreeOfFreedom *fineDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); - DOFAdmin *admin = feSpace->getAdmin(); + DOFAdmin *admin = feSpace->getAdmin(); std::vector<std::vector<DegreeOfFreedom> > sendOrder(mpiSize); std::vector<std::vector<DegreeOfFreedom> > recvOrder(mpiSize); @@ -522,7 +587,7 @@ namespace AMDiS { if (partitionData) { if (partitionData->getLevel() == 0) { - elementPartition = partitionVec_[element->getIndex()]; + elementPartition = partitionVec[element->getIndex()]; } PartitionStatus status = partitionData->getPartitionStatus(); @@ -533,8 +598,8 @@ namespace AMDiS { // collect other partitions element belongs to for (int i = 0; i < dim + 1; i++) { - std::set<int>::iterator setBegin = vertexPartitions_[coarseDOFs[i]].begin(); - std::set<int>::iterator setEnd = vertexPartitions_[coarseDOFs[i]].end(); + std::set<int>::iterator setBegin = vertexPartitions[coarseDOFs[i]].begin(); + std::set<int>::iterator setEnd = vertexPartitions[coarseDOFs[i]].end(); for (std::set<int>::iterator setIt = setBegin; setIt != setEnd; ++setIt) { elementPartitions_[element].insert(*setIt); } @@ -586,34 +651,34 @@ namespace AMDiS { sendBufferSize[partition] = sendSize; recvBufferSize[partition] = recvSize; - if(sendSize > 0) { + if (sendSize > 0) { sendBuffer[partition] = GET_MEMORY(double, sendSize); std::vector<DegreeOfFreedom>::iterator dofIt; dofIt = sendOrder[partition].begin(); double *bufferIt, *bufferBegin, *bufferEnd; bufferBegin = sendBuffer[partition]; bufferEnd = bufferBegin + sendSize; - for(bufferIt = bufferBegin; - bufferIt < bufferEnd; - ++bufferIt, ++dofIt) - { + for (bufferIt = bufferBegin; + bufferIt < bufferEnd; + ++bufferIt, ++dofIt) { *bufferIt = (*solution)[*dofIt]; } } - if(recvSize > 0) + if (recvSize > 0) { recvBuffer[partition] = GET_MEMORY(double, recvSize); + } } } // non-blocking sends for (int partition = 0; partition < mpiSize; partition++) { if (partition != mpiRank) { - if(sendBufferSize[partition] > 0) { - MPI::COMM_WORLD.Isend(sendBuffer[partition], - sendBufferSize[partition], - MPI_DOUBLE, - partition, - 0); + if (sendBufferSize[partition] > 0) { + mpiComm.Isend(sendBuffer[partition], + sendBufferSize[partition], + MPI_DOUBLE, + partition, + 0); } } } @@ -622,17 +687,17 @@ namespace AMDiS { for (int partition = 0; partition < mpiSize; partition++) { if (partition != mpiRank) { if (recvBufferSize[partition] > 0) { - MPI::COMM_WORLD.Recv(recvBuffer[partition], - recvBufferSize[partition], - MPI_DOUBLE, - partition, - 0); + mpiComm.Recv(recvBuffer[partition], + recvBufferSize[partition], + MPI_DOUBLE, + partition, + 0); } } } // wait for end of communication - MPI::COMM_WORLD.Barrier(); + mpiComm.Barrier(); // copy values into rank solutions for (int partition = 0; partition < mpiSize; partition++) { @@ -648,14 +713,12 @@ namespace AMDiS { // free send and recv buffers for (int partition = 0; partition < mpiSize; partition++) { if (partition != mpiRank) { - if (sendBufferSize[partition] > 0) - FREE_MEMORY(sendBuffer[partition], - double, - sendBufferSize[partition]); - if(recvBufferSize[partition] > 0) - FREE_MEMORY(recvBuffer[partition], - double, - recvBufferSize[partition]); + if (sendBufferSize[partition] > 0) { + FREE_MEMORY(sendBuffer[partition], double, sendBufferSize[partition]); + } + if (recvBufferSize[partition] > 0) { + FREE_MEMORY(recvBuffer[partition], double, recvBufferSize[partition]); + } } } @@ -666,8 +729,8 @@ namespace AMDiS { void ParallelProblem::exchangeDOFVector(AdaptInfo *adaptInfo, DOFVector<double> *values) { - partitioner_->fillLeafPartitionVec(&oldPartitionVec_, &oldPartitionVec_); - partitioner_->fillLeafPartitionVec(&partitionVec_, &partitionVec_); + partitioner_->fillLeafPartitionVec(&oldPartitionVec, &oldPartitionVec); + partitioner_->fillLeafPartitionVec(&partitionVec, &partitionVec); // === get send and recieve orders === std::vector<std::vector<DegreeOfFreedom> > sendOrder; @@ -690,8 +753,8 @@ namespace AMDiS { while(elInfo) { Element *element = elInfo->getElement(); int index = element->getIndex(); - int oldPartition = oldPartitionVec_[index]; - int newPartition = partitionVec_[index]; + int oldPartition = oldPartitionVec[index]; + int newPartition = partitionVec[index]; if(oldPartition != newPartition) { // get dof indices @@ -723,77 +786,65 @@ namespace AMDiS { std::map<int, int> recvBufferSize; int partition; - for(partition = 0; partition < mpiSize; partition++) { - if(partition != mpiRank) { + for (partition = 0; partition < mpiSize; partition++) { + if (partition != mpiRank) { int sendSize = static_cast<int>(sendOrder[partition].size()); int recvSize = static_cast<int>(recvOrder[partition].size()); sendBufferSize[partition] = sendSize; recvBufferSize[partition] = recvSize; - if(sendSize > 0) { + if (sendSize > 0) { sendBuffer[partition] = GET_MEMORY(double, sendSize); std::vector<DegreeOfFreedom>::iterator dofIt; dofIt = sendOrder[partition].begin(); double *bufferIt, *bufferBegin, *bufferEnd; bufferBegin = sendBuffer[partition]; bufferEnd = bufferBegin + sendSize; - for(bufferIt = bufferBegin; - bufferIt < bufferEnd; - ++bufferIt, ++dofIt) - { + for (bufferIt = bufferBegin; + bufferIt < bufferEnd; + ++bufferIt, ++dofIt) { *bufferIt = (*values)[*dofIt]; } } - if(recvSize > 0) + if (recvSize > 0) recvBuffer[partition] = GET_MEMORY(double, recvSize); } } -// MSG("rank %d: send %d %d %d %d recv %d %d %d %d\n", -// mpiRank, -// sendBufferSize[0], -// sendBufferSize[1], -// sendBufferSize[2], -// sendBufferSize[3], -// recvBufferSize[0], -// recvBufferSize[1], -// recvBufferSize[2], -// recvBufferSize[3]); - // === non-blocking sends === - for(partition = 0; partition < mpiSize; partition++) { - if(partition != mpiRank) { - if(sendBufferSize[partition] > 0) { - MPI::COMM_WORLD.Isend(sendBuffer[partition], - sendBufferSize[partition], - MPI_DOUBLE, - partition, - 0); + for (partition = 0; partition < mpiSize; partition++) { + if (partition != mpiRank) { + if (sendBufferSize[partition] > 0) { + mpiComm.Isend(sendBuffer[partition], + sendBufferSize[partition], + MPI_DOUBLE, + partition, + 0); } } } // === blocking receives === - for(partition = 0; partition < mpiSize; partition++) { - if(partition != mpiRank) { - if(recvBufferSize[partition] > 0) { - MPI::COMM_WORLD.Recv(recvBuffer[partition], - recvBufferSize[partition], - MPI_DOUBLE, - partition, - 0); + for (partition = 0; partition < mpiSize; partition++) { + if (partition != mpiRank) { + if (recvBufferSize[partition] > 0) { + mpiComm.Recv(recvBuffer[partition], + recvBufferSize[partition], + MPI_DOUBLE, + partition, + 0); } } } // === wait for end of MPI communication === - MPI::COMM_WORLD.Barrier(); + mpiComm.Barrier(); // === copy received values into DOFVector === - for(partition = 0; partition < mpiSize; partition++) { - if(partition != mpiRank) { + for (partition = 0; partition < mpiSize; partition++) { + if (partition != mpiRank) { std::vector<DegreeOfFreedom>::iterator dofIt = recvOrder[partition].begin(); - for(i = 0; i < recvBufferSize[partition]; i++) { + for (i = 0; i < recvBufferSize[partition]; i++) { (*values)[*dofIt] = recvBuffer[partition][i]; ++dofIt; } @@ -801,13 +852,13 @@ namespace AMDiS { } // === free send and receive buffers === - for(partition = 0; partition < mpiSize; partition++) { - if(partition != mpiRank) { - if(sendBufferSize[partition] > 0) + for (partition = 0; partition < mpiSize; partition++) { + if (partition != mpiRank) { + if (sendBufferSize[partition] > 0) FREE_MEMORY(sendBuffer[partition], double, sendBufferSize[partition]); - if(recvBufferSize[partition] > 0) + if (recvBufferSize[partition] > 0) FREE_MEMORY(recvBuffer[partition], double, recvBufferSize[partition]); @@ -891,8 +942,8 @@ namespace AMDiS { // for all coarse vertex DOFs for (int j = 0; j < dim + 1; j++) { - partBegin = vertexPartitions_[coarseDOFs[j]].begin(); - partEnd = vertexPartitions_[coarseDOFs[j]].end(); + partBegin = vertexPartitions[coarseDOFs[j]].begin(); + partEnd = vertexPartitions[coarseDOFs[j]].end(); for (partIt = partBegin; partIt != partEnd; ++partIt) { int partition = *partIt/* - 1*/; double val = (*(linearFunctions->getPhi(j)))(baryCoord); @@ -943,7 +994,8 @@ namespace AMDiS { int elNum = -1; double totalErr, error; - if(!add) errVec.clear(); + if (!add) + errVec.clear(); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, @@ -1036,7 +1088,7 @@ namespace AMDiS { void ParallelProblem::createOverlap(int level, int overlap, bool openOverlap, std::map<Element*, int> &overlapDistance) { - int i, dim = mesh->getDim(); + int dim = mesh->getDim(); // === create dual graph (one common node) and prepare breadth-first search === std::map<DegreeOfFreedom, std::vector<Element*> > vertexElements; @@ -1044,14 +1096,14 @@ namespace AMDiS { TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); - while(elInfo) { + while (elInfo) { Element *element = elInfo->getElement(); PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>(element->getElementData(PARTITION_ED)); - if(partitionData) { - if(partitionData->getLevel() == level) { - for(i = 0; i < dim + 1; i++) { + if (partitionData) { + if (partitionData->getLevel() == level) { + for (int i = 0; i < dim + 1; i++) { vertexElements[element->getDOF(i, 0)].push_back(element); } @@ -1069,7 +1121,7 @@ namespace AMDiS { // === breadth-first search on dual graph === std::vector<Element*>::iterator it, itBegin, itEnd; - while(!overlapQueue.empty()) { + while (!overlapQueue.empty()) { // get first element in queue Element *element = overlapQueue.front(); overlapQueue.pop(); @@ -1078,14 +1130,15 @@ namespace AMDiS { int distance = overlapDistance[element]; TEST_EXIT(distance >= 0)("invalid distance\n"); - if(distance >= overlap) continue; + if (distance >= overlap) + continue; // get all adjacent elements - for(i = 0; i < dim + 1; i++) { + for (int i = 0; i < dim + 1; i++) { itBegin = vertexElements[element->getDOF(i, 0)].begin(); itEnd = vertexElements[element->getDOF(i, 0)].end(); - for(it = itBegin; it != itEnd; ++it) { - if(overlapDistance[*it] == -1) { + for (it = itBegin; it != itEnd; ++it) { + if (overlapDistance[*it] == -1) { // set distance for new member overlapDistance[*it] = distance + 1; // push neighbour to queue @@ -1108,27 +1161,24 @@ namespace AMDiS { { int dim = mesh->getDim(); - TraverseStack stack; - ElInfo *elInfo; - // clear partition dof vector - vertexPartitions_.clear(); + vertexPartitions.clear(); // first: partition elements ... - int index, partition; - elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + int partition; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); while (elInfo) { Element *element = elInfo->getElement(); PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>(element->getElementData(PARTITION_ED)); if (partitionData) { if (partitionData->getLevel() == 0) { - index = element->getIndex(); - partition = partitionVec_[index]; + partition = partitionVec[element->getIndex()]; } if (partitionData->getLevel() == level) { for (int i = 0; i < dim + 1; i++) { - vertexPartitions_[element->getDOF(i, 0)].insert(partition); + vertexPartitions[element->getDOF(i, 0)].insert(partition); } } } @@ -1141,9 +1191,8 @@ namespace AMDiS { exchangeMeshStructureCodes(structures); // merge codes - int rank; - for(rank = 0; rank < mpiSize; rank++) { - if(rank != mpiRank) { + for (int rank = 0; rank < mpiSize; rank++) { + if (rank != mpiRank) { structures[mpiRank].merge(&structures[rank]); } } @@ -1185,13 +1234,12 @@ namespace AMDiS { // exchange number of overlap elements int *numOverlapElements = GET_MEMORY(int, mpiSize); int tmp = static_cast<int>(innerOverlapElements.size()); - MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, - numOverlapElements, 1, MPI_INT); + mpiComm.Allgather(&tmp, 1, MPI_INT, numOverlapElements, 1, MPI_INT); // exchange overlap elements int *offset = GET_MEMORY(int, mpiSize); int sum = 0; - for(rank = 0; rank < mpiSize; rank++) { + for (int rank = 0; rank < mpiSize; rank++) { offset[rank] = sum; sum += numOverlapElements[rank]; } @@ -1202,31 +1250,24 @@ namespace AMDiS { int *ptr; std::vector<int>::iterator elemIt, elemEnd = innerOverlapElements.end(); - for(ptr = sendBuffer, elemIt = innerOverlapElements.begin(); - elemIt != elemEnd; - ++elemIt, ++ptr) - { + for (ptr = sendBuffer, elemIt = innerOverlapElements.begin(); + elemIt != elemEnd; + ++elemIt, ++ptr) { *ptr = *elemIt; } - MPI::COMM_WORLD.Allgatherv(sendBuffer, numOverlapElements[mpiRank], - MPI_INT, - recvBuffer, numOverlapElements, offset, - MPI_INT); - + mpiComm.Allgatherv(sendBuffer, numOverlapElements[mpiRank], MPI_INT, + recvBuffer, numOverlapElements, offset, MPI_INT); // fill vertexPartitions for 'inner' overlap elements - int el; - for (rank = 0; rank < mpiSize; rank++) { + for (int rank = 0; rank < mpiSize; rank++) { int numElements = numOverlapElements[rank]; - // MSG("rank %d overlap elements with %d: %d\n", - // mpiRank, rank, numOverlapElements[rank]); int *elements = recvBuffer + offset[rank]; - for (el = 0; el < numElements; el++) { + for (int el = 0; el < numElements; el++) { Element *element = indexElement[elements[el]]; for (int i = 0; i < dim + 1; i++) { - vertexPartitions_[element->getDOF(i, 0)].insert(rank/* + 1*/); + vertexPartitions[element->getDOF(i, 0)].insert(rank/* + 1*/); } } } @@ -1273,20 +1314,7 @@ namespace AMDiS { for (int i = 0; i < mpiSize; i++) { rankSolution[i] = NEW DOFVector<double>(problem->getFESpace(), "rank solution"); } - - // Create vectors for debuging information - if (debugMode) { - dbgRankSolution.resize(mpiSize); - for (int i = 0; i < mpiSize; i++) { - dbgRankSolution[i] = NEW DOFVector<double>(problem->getFESpace(), "debug rank solution"); - } - - if (mpiRank == 0) { - dbgSolution = NEW DOFVector<double>(problem->getFESpace(), "debug solution"); - } - } - - + if (problemInstat_) { dofVectors_.push_back(problemInstat_->getOldSolution()); } @@ -1297,16 +1325,6 @@ namespace AMDiS { for (int i = 0; i < mpiSize; i++) { DELETE rankSolution[i]; } - - if (debugMode) { - for (int i = 0; i < mpiSize; i++) { - DELETE dbgRankSolution[i]; - } - - if (mpiRank == 0) { - DELETE dbgSolution; - } - } } @@ -1419,13 +1437,6 @@ namespace AMDiS { ParallelProblem::exchangeRankSolutions(adaptInfo, mesh, rankSolution); - - if (debugMode) { - dbgRankSolution[mpiRank]->copy(*(problem->getSolution())); - ParallelProblem::exchangeRankSolutions(adaptInfo, - dbgMesh, - dbgRankSolution); - } } void ParallelProblemScal::buildGlobalSolution(AdaptInfo *adaptInfo) @@ -1433,12 +1444,6 @@ namespace AMDiS { ParallelProblem::buildGlobalSolution(adaptInfo, rankSolution, problem->getSolution()); - - if (debugMode && mpiRank == 0) { - ParallelProblem::buildGlobalSolution(adaptInfo, - dbgRankSolution, - dbgSolution); - } } void ParallelProblemScal::coarsenOutOfPartition(AdaptInfo *adaptInfo) @@ -1484,24 +1489,6 @@ namespace AMDiS { } } - if (debugMode) { - dbgRankSolution.resize(mpiSize); - for (int i = 0; i < mpiSize; i++) { - dbgRankSolution[i] = NEW SystemVector("debug rank solution", feSpaces, nComponents); - for (int j = 0; j < nComponents; j++) { - dbgRankSolution[i]->setDOFVector(j, NEW DOFVector<double>(feSpaces[j], - "debug rank solution")); - } - } - - if (mpiRank == 0) { - dbgSolution = NEW SystemVector("debug solution", feSpaces, nComponents); - for (int i = 0; i < nComponents; i++) { - dbgSolution->setDOFVector(i, NEW DOFVector<double>(feSpaces[i], "debug solution")); - } - } - } - if (problemInstat_) { for (int i = 0; i < nComponents; i++) { dofVectors_.push_back(problemInstat_->getOldSolution()->getDOFVector(i)); @@ -1517,22 +1504,6 @@ namespace AMDiS { } DELETE rankSolution[i]; } - - if (debugMode) { - for (int i = 0; i < mpiSize; i++) { - for (int j = 0; j < nComponents; j++) { - DELETE dbgRankSolution[i]->getDOFVector(j); - } - DELETE dbgRankSolution[i]; - } - - if (mpiRank == 0) { - for (int i = 0; i < nComponents; i++) { - DELETE dbgSolution->getDOFVector(i); - } - DELETE dbgSolution; - } - } } void ParallelProblemVec::initParallelization(AdaptInfo *adaptInfo) @@ -1580,7 +1551,7 @@ namespace AMDiS { // modify file writers char number[10]; - sprintf(number, "%d", MPI::COMM_WORLD.Get_rank()); + sprintf(number, "%d", mpiComm.Get_rank()); ::std::vector<FileWriterInterface*> fileWriters = problem->getFileWriterList(); ::std::vector<FileWriterInterface*>::iterator fwIt, fwBegin, fwEnd; fwBegin = fileWriters.begin(); @@ -1633,10 +1604,6 @@ namespace AMDiS { void ParallelProblemVec::exchangeRankSolutions(AdaptInfo *adaptInfo) { rankSolution[mpiRank]->copy(*(problem->getSolution())); - if (debugMode) { - dbgRankSolution[mpiRank]->copy(*(problem->getSolution())); - } - std::vector<DOFVector<double>*> rankSol(mpiSize); for (int i = 0; i < nComponents; i++) { @@ -1646,15 +1613,24 @@ namespace AMDiS { ParallelProblem::exchangeRankSolutions(adaptInfo, mesh, rankSol); + } - if (debugMode) { - for (int j = 0; j < mpiSize; j++) { - rankSol[j] = dbgRankSolution[j]->getDOFVector(i); - } - ParallelProblem::exchangeRankSolutions(adaptInfo, - dbgMesh, - rankSol); + // In debug mode, mpiRank 0 sends the map partitionVec, which is + // equal on all ranks, to the debug server. + if (debugMode && mpiRank == 0) { + int sendSize = partitionVec.size() * 2; + MPI::COMM_WORLD.Send(&sendSize, 1, MPI_INT, 0, 100); + + int *sendBuffer = GET_MEMORY(int, sendSize); + int bufferPos = 0; + for (std::map<int, int>::iterator it = partitionVec.begin(); + it != partitionVec.end(); + ++it) { + sendBuffer[bufferPos++] = it->first; + sendBuffer[bufferPos++] = it->second; } + MPI::COMM_WORLD.Send(sendBuffer, sendSize, MPI_INT, 0, 100); + FREE_MEMORY(sendBuffer, int, sendSize); } } @@ -1669,15 +1645,55 @@ namespace AMDiS { ParallelProblem::buildGlobalSolution(adaptInfo, rankSol, problem->getSolution()->getDOFVector(i)); + } + + // In debug mode, every rank sends its solution to the debug server. + if (debugMode) { + const FiniteElemSpace *feSpace = problem->getFESpace(0); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + DOFAdmin *admin = feSpace->getAdmin(); + int numFcts = basFcts->getNumber(); + DegreeOfFreedom *elDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + + int elementPartition = -1; + std::vector<double> sendDOFs(0); + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + Element *element = elInfo->getElement(); + + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if (partitionData && (partitionData->getLevel() == 0)) { + elementPartition = partitionVec[element->getIndex()]; + } + + // On leaf level, each rank assemble its own solution part. + if (element->isLeaf() && (elementPartition == mpiRank)) { + basFcts->getLocalIndices(element, admin, elDOFs); - if (debugMode && mpiRank == 0) { - for (int j = 0; j < mpiSize; j++) { - rankSol[j] = dbgRankSolution[j]->getDOFVector(i); + for (int i = 0; i < numFcts; i++) { + sendDOFs.push_back((*problem->getSolution()->getDOFVector(0))[elDOFs[i]]); + } } - ParallelProblem::buildGlobalSolution(adaptInfo, - rankSol, - dbgSolution->getDOFVector(i)); + + elInfo = stack.traverseNext(elInfo); + } + + // First, send number of values the will be send after that. + int sendSize = sendDOFs.size(); + MPI::COMM_WORLD.Send(&sendSize, 1, MPI_INT, 0, 100); + + // Create send buffer of values and send it to the debug server. + double *sendBuffer = GET_MEMORY(double, sendSize); + for (int i = 0; i < sendSize; i++) { + sendBuffer[i] = sendDOFs[i]; } + MPI::COMM_WORLD.Send(sendBuffer, sendSize, MPI_DOUBLE, 0, 100); + + FREE_MEMORY(sendBuffer, double, sendSize); + FREE_MEMORY(elDOFs, DegreeOfFreedom, numFcts); } } @@ -1711,4 +1727,126 @@ namespace AMDiS { } } + void ParallelProblemVec::startDebugServer() + { + FUNCNAME("ParallelProblemVec::startDebugServer()"); + + TEST_EXIT(debugMode)("Debug server applicable only in debug mode!\n"); + + const FiniteElemSpace *feSpace = problem->getFESpace(0); + DOFAdmin *admin = feSpace->getAdmin(); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int numFcts = basFcts->getNumber(); + int mpiWorldSize = MPI::COMM_WORLD.Get_size(); + int *codeSize = GET_MEMORY(int, mpiWorldSize); + int *nElements = GET_MEMORY(int, mpiWorldSize); + DegreeOfFreedom *elDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + unsigned long int *code; + int mpiTag = 100; + + while (true) { + MeshStructure *structures = NEW MeshStructure[mpiWorldSize]; + + /* ===== Communication with exchangeMeshStructureCode() ====== */ + + // Get mesh structure code size of all meshes + MPI::COMM_WORLD.Gather(&codeSize, 1, MPI_INT, codeSize, 1, MPI_INT, 0); + + // Get number of elements of all meshes + MPI::COMM_WORLD.Gather(&nElements, 1, MPI_INT, nElements, 1, MPI_INT, 0); + + // Get all mesh structure codes + for (int i = 1; i < mpiWorldSize; i++) { + code = GET_MEMORY(unsigned long int, codeSize[i]); + + MPI::COMM_WORLD.Recv(code, codeSize[i], MPI_UNSIGNED_LONG, + i, mpiTag); + + std::vector<unsigned long int> codeVec(codeSize[i]); + for (int j = 0; j < codeSize[i]; j++) { + codeVec[j] = code[j]; + } + structures[i].init(codeVec, nElements[i]); + + FREE_MEMORY(code, unsigned long int, codeSize[i]); + } + + + /* ======== Simulate synchronizeMeshes() ======= */ + + // Build finest mesh starting from rank 1 solution + for (int rank = 2; rank < mpiWorldSize; rank++) { + structures[1].merge(&structures[rank]); + } + + structures[1].fitMeshToStructure(mesh, refinementManager, false); + + DELETE [] structures; + + + /* ======= Communication with exchangeRankSolution() ======= */ + + // receive the vector partitionVec from COMM_WORLD.rank = 1 to know + // the mesh partitioning on localCoarseGridLevel + int recvSize = 0; + MPI::COMM_WORLD.Recv(&recvSize, 1, MPI_INT, 1, mpiTag); + + int *recvBuffer = GET_MEMORY(int, recvSize); + MPI::COMM_WORLD.Recv(recvBuffer, recvSize, MPI_INT, 1, mpiTag); + partitionVec.clear(); + for (int i = 0; i < recvSize; i += 2) { + partitionVec[recvBuffer[i]] = recvBuffer[i + 1]; + } + FREE_MEMORY(recvBuffer, int, recvSize); + + + /* ======= Communication with buildGlobalSolution() ======= */ + + // Get final solutions from all ranks + for (int i = 1; i < mpiSize; i++) { + // First, get number of DOFs that will be send from rank i + MPI::COMM_WORLD.Recv(&recvSize, 1, MPI_INT, i, mpiTag); + + // Now, receive the solution DOFS of rank i + double *recvBufferDouble = GET_MEMORY(double, recvSize); + MPI::COMM_WORLD.Recv(recvBufferDouble, recvSize, MPI_DOUBLE, i, mpiTag); + + // Traverse through the overall mesh, get all elements that are refined from + // an element with localCoarseGridLevel i, and set there the solutions DOFs. + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + int elementOwner = -1; + int dofCount = 0; + while (elInfo) { + Element *element = elInfo->getElement(); + if (partitionVec.count(element->getIndex()) > 0) { + elementOwner = partitionVec[element->getIndex()]; + } + + if (element->isLeaf()) { + basFcts->getLocalIndices(element, admin, elDOFs); + if (elementOwner == (i - 1)) { + for (int i = 0; i < numFcts; i++) { + (*problem->getSolution()->getDOFVector(0))[elDOFs[i]] = + recvBufferDouble[dofCount + i]; + } + dofCount += numFcts; + } + } + + elInfo = stack.traverseNext(elInfo); + } + + FREE_MEMORY(recvBufferDouble, double, recvSize); + } + + + /* ====== Finally, call debug function ====== */ + debugFunction(); + } + + FREE_MEMORY(elDOFs, DegreeOfFreedom, numFcts); + FREE_MEMORY(codeSize, int, mpiWorldSize); + FREE_MEMORY(nElements, int, mpiWorldSize); + } } diff --git a/AMDiS/src/ParallelProblem.h b/AMDiS/src/ParallelProblem.h index 74518172e561b211d4f5d8f9b965c8dc7c82f791..1763f7fc992423f04fb3e2227bb2d663ea526279 100644 --- a/AMDiS/src/ParallelProblem.h +++ b/AMDiS/src/ParallelProblem.h @@ -59,7 +59,8 @@ namespace AMDiS { public ProblemTimeInterface { public: - ParallelProblemBase(ProblemIterationInterface *iterationIF, + ParallelProblemBase(const std::string& name, + ProblemIterationInterface *iterationIF, ProblemTimeInterface *timeIF); virtual ~ParallelProblemBase() {}; @@ -101,11 +102,7 @@ namespace AMDiS { */ virtual void buildGlobalSolution(AdaptInfo *adaptInfo) = 0; - virtual void exitParallelization(AdaptInfo *adaptInfo) - { - if (!timeIF_) - closeTimestep(adaptInfo); - }; + virtual void exitParallelization(AdaptInfo *adaptInfo); virtual void setTime(AdaptInfo *adaptInfo) { @@ -149,50 +146,7 @@ namespace AMDiS { iterationIF_->beginIteration(adaptInfo); }; - virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION) - { - Flag flag; - - if (mpiSize > 1 && toDo.isSet(MARK | ADAPT)) { - flag = iterationIF_->oneIteration(adaptInfo, MARK | ADAPT); - - double localWeightSum = setElemWeights(adaptInfo); - if (doPartitioning(adaptInfo, localWeightSum)) { - clock_t partitioningStart = clock(); - - synchronizeMeshes(adaptInfo); - partitionMesh(adaptInfo); - refineOverlap(adaptInfo); - createOverlap(adaptInfo); - synchronizeMeshes(adaptInfo); - exchangeDOFVectors(adaptInfo); - coarsenOutOfPartition(adaptInfo); - - clock_t partitioningEnd = clock(); - partitioningTime = TIME_USED(partitioningStart, - partitioningEnd); - computationStart = partitioningEnd; - } - - flag |= iterationIF_->oneIteration(adaptInfo, toDo & ~(MARK | ADAPT)); - } else { - flag = iterationIF_->oneIteration(adaptInfo, toDo); - } - - // synchronize adaption flag - unsigned long *flagBuffer = GET_MEMORY(unsigned long, mpiSize); - - unsigned long localFlag = flag.getFlags(); - - MPI::COMM_WORLD.Allgather(&localFlag, 1, MPI_UNSIGNED_LONG, - flagBuffer, 1, MPI_UNSIGNED_LONG); - for (int i = 0; i < mpiSize; i++) { - flag.setFlag(flagBuffer[i]); - } - FREE_MEMORY(flagBuffer, unsigned long, mpiSize); - - return flag; - }; + virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION); virtual void endIteration(AdaptInfo *adaptInfo) { iterationIF_->endIteration(adaptInfo); @@ -204,12 +158,15 @@ namespace AMDiS { return false; }; + MPI::Intracomm* getMpiComm() { + return &mpiComm; + }; - protected: - int mpiRank; - - int mpiSize; + bool getDebugServerProcess() { + return debugServerProcess; + } + protected: ProblemIterationInterface *iterationIF_; ProblemTimeInterface *timeIF_; @@ -217,6 +174,41 @@ namespace AMDiS { clock_t computationStart; double partitioningTime; + + /** \brief + * The rank of the current process. + */ + int mpiRank; + + /** \brief + * Overall number of processes. + */ + int mpiSize; + + /** \brief + * MPI communicator collected all processes, which should + * be used for calculation. The Debug procces is not included + * in this communicator. + */ + MPI::Intracomm mpiComm; + + /** \brief + * The MPI group, which is used for the communicator + * \ref mpiComm. + */ + MPI::Group amdisGroup; + + /** \brief + * Defines the debug mode. If it is 1, a debug server will be started + * on rank 0. + */ + int debugMode; + + /** \brief + * If true, the current process is the debug server. Otherwise, the + * processes is a working processes calculating part of the solution. + */ + bool debugServerProcess; }; // ========================================================================= @@ -296,9 +288,7 @@ namespace AMDiS { static bool writeElement(ElInfo *elInfo); - Mesh* getDbgMesh() { - return dbgMesh; - } + virtual void startDebugServer() {}; virtual void serialize(std::ostream&) {}; @@ -338,15 +328,16 @@ namespace AMDiS { ParMetisPartitioner *partitioner_; /** \brief - * Stores to every element index the number of the partition it corresponds to. + * Stores to every coarse element index the number of the partition it + * corresponds to. */ - std::map<int, int> partitionVec_; + std::map<int, int> partitionVec; /** \brief - * Stores an old partitioning of elements. To every element index the number of - * the parition it corresponds to is stored. + * Stores an old partitioning of elements. To every element index the number + * of the parition it corresponds to is stored. */ - std::map<int, int> oldPartitionVec_; + std::map<int, int> oldPartitionVec; /** \brief * @@ -354,14 +345,14 @@ namespace AMDiS { std::map<int, double> elemWeights_; /** \brief - * + * Stores to every element the set of partitions it corresponds to. */ std::map<Element*, std::set<int> > elementPartitions_; /** \brief * Stores to every DOF the set of partitions it corresponds to. */ - std::map<DegreeOfFreedom, std::set<int> > vertexPartitions_; + std::map<DegreeOfFreedom, std::set<int> > vertexPartitions; /** \brief * @@ -437,20 +428,6 @@ namespace AMDiS { * */ double maxLowerTH_; - - /** \brief - * Defines the debug mode. If it is 1, the processor with rank 0 - * fills \ref dbgMesh, which than contains the whole mesh domain after - * each timestep. This makes it easy to check the whole result without - * manually fitting the subresults together. - */ - int debugMode; - - /** \brief - * In debug mode on process 0, this mesh contains the composition of all - * rank meshes. - */ - Mesh *dbgMesh; }; // ========================================================================= @@ -517,18 +494,6 @@ namespace AMDiS { */ std::vector<DOFVector<double>*> rankSolution; - /** \brief - * Is used in debug mode in the same context as \ref rankSolution. - * But the solution is build using \ref dbgMesh. - */ - std::vector<DOFVector<double>*> dbgRankSolution; - - /** \brief - * In debug mode and on process 0 only, this vector will be initialized - * to store the overall solution of all processes. - */ - DOFVector<double>* dbgSolution; - /** \brief * */ @@ -588,9 +553,9 @@ namespace AMDiS { return name_; }; - SystemVector* getDbgSolution() { - return dbgSolution; - }; + virtual void startDebugServer(); + + virtual void debugFunction() {}; protected: ProblemVec *problem; @@ -615,18 +580,6 @@ namespace AMDiS { */ std::vector<SystemVector*> rankSolution; - /** \brief - * Is used in debug mode in the same context as \ref rankSolution. - * But the solution is build using \ref dbgMesh. - */ - std::vector<SystemVector*> dbgRankSolution; - - /** \brief - * In debug mode and on process 0 only, this vector will be initialized - * to store the overall solution of all processes. - */ - SystemVector* dbgSolution; - /** \brief * */ diff --git a/AMDiS/src/PartitionElementData.h b/AMDiS/src/PartitionElementData.h index b7fcb748ce53fcd63a63f07e0d31e55d9581c960..03de5d114329054d71abc0b588d0004d1391c38e 100644 --- a/AMDiS/src/PartitionElementData.h +++ b/AMDiS/src/PartitionElementData.h @@ -58,8 +58,8 @@ namespace AMDiS { PartitionElementData(ElementData *decorated = NULL) : ElementData(decorated), - status_(UNDEFINED), - level_(0) + status(UNDEFINED), + level(0) {}; bool refineElementData(Element* parent, @@ -70,10 +70,10 @@ namespace AMDiS { ElementData::refineElementData(parent, child1, child2, elType); PartitionElementData *child1Data = NEW PartitionElementData(child1->getElementData()); PartitionElementData *child2Data = NEW PartitionElementData(child2->getElementData()); - child1Data->setPartitionStatus(status_); - child2Data->setPartitionStatus(status_); - child1Data->setLevel(level_ + 1); - child2Data->setLevel(level_ + 1); + child1Data->setPartitionStatus(status); + child2Data->setPartitionStatus(status); + child1Data->setLevel(level + 1); + child2Data->setLevel(level + 1); child1->setElementData(child1Data); child2->setElementData(child2Data); return false; @@ -96,33 +96,31 @@ namespace AMDiS { void serialize(std::ostream& out) { ElementData::serialize(out); - out.write(reinterpret_cast<const char*>(&status_), - sizeof(PartitionStatus)); - out.write(reinterpret_cast<const char*>(&level_), sizeof(int)); + out.write(reinterpret_cast<const char*>(&status), sizeof(PartitionStatus)); + out.write(reinterpret_cast<const char*>(&level), sizeof(int)); }; void deserialize(std::istream& in) { ElementData::deserialize(in); - in.read(reinterpret_cast<char*>(&status_), - sizeof(PartitionStatus)); - in.read(reinterpret_cast<char*>(&level_), sizeof(int)); + in.read(reinterpret_cast<char*>(&status), sizeof(PartitionStatus)); + in.read(reinterpret_cast<char*>(&level), sizeof(int)); }; - inline void setPartitionStatus(PartitionStatus status) { - status_ = status; + inline void setPartitionStatus(PartitionStatus status_) { + status = status_; }; inline PartitionStatus getPartitionStatus() { - return status_; + return status; }; - inline void setLevel(int level) { - level_ = level; + inline void setLevel(int level_) { + level = level_; }; inline int getLevel() { - return level_; + return level; }; void descend(Element *element) @@ -148,8 +146,9 @@ namespace AMDiS { }; protected: - PartitionStatus status_; - int level_; + PartitionStatus status; + + int level; }; } diff --git a/AMDiS/src/ProblemIterationInterface.h b/AMDiS/src/ProblemIterationInterface.h index 0c2bca5dcaf09002d0914f4099c317f7b3d4e3d7..d8d6c266230223724708acaf49cf2bc1606ca59c 100644 --- a/AMDiS/src/ProblemIterationInterface.h +++ b/AMDiS/src/ProblemIterationInterface.h @@ -84,9 +84,7 @@ namespace AMDiS { /** \brief * Returns the problem with the given name. */ - virtual ProblemStatBase *getProblem(const ::std::string& name) { - return NULL; - }; + virtual ProblemStatBase *getProblem(const ::std::string& name) { return NULL; }; /** \brief * Returns the name of the problem. diff --git a/AMDiS/src/ProblemScal.h b/AMDiS/src/ProblemScal.h index 6abf2784f81c61964996496883e25b0b747cbcee..3d42a2bd484f86915149142994a4d26571250dfb 100644 --- a/AMDiS/src/ProblemScal.h +++ b/AMDiS/src/ProblemScal.h @@ -177,24 +177,18 @@ namespace AMDiS { /** \brief * Returns number of managed problems */ - virtual int getNumProblems() { - return 1; - }; + virtual int getNumProblems() { return 1; }; /** \brief * Implementation of ProblemStatBase::getNumComponents() */ - virtual int getNumComponents() { - return 1; - }; + virtual int getNumComponents() { return 1; }; /** \brief * Returns the problem with the given number. If only one problem * is managed by this master problem, the number hasn't to be given. */ - virtual ProblemStatBase *getProblem(int number = 0) { - return this; - }; + virtual ProblemStatBase *getProblem(int number = 0) { return this; }; /** \brief * Writes output files. diff --git a/AMDiS/src/Serializer.h b/AMDiS/src/Serializer.h index cf8b595160d2130d4d0f234b3854c6ac1fbc87f8..ba4f607925f1db29412df9e5555ac21f24f07c6d 100644 --- a/AMDiS/src/Serializer.h +++ b/AMDiS/src/Serializer.h @@ -39,18 +39,14 @@ namespace AMDiS { Serializer(ProblemType *problem) : name_(""), problem_(problem), - tsModulo(1), + tsModulo_(1), timestepNumber_(-1) { GET_PARAMETER(0, problem_->getName() + "->output->serialization filename", &name_); GET_PARAMETER(0, problem_->getName() + "->output->write every i-th timestep", - "%d", &tsModulo); - + "%d", &tsModulo_); TEST_EXIT(name_ != "")("no filename\n"); - - TEST_EXIT(tsModulo > 0) - ("Init file option \"write every i-th timestep\" is smaller than 1!\n"); }; virtual ~Serializer() {}; @@ -64,7 +60,7 @@ namespace AMDiS { FUNCNAME("Serializer::writeFiles()"); timestepNumber_++; - timestepNumber_ %= tsModulo; + timestepNumber_ %= tsModulo_; if ((timestepNumber_ != 0) && !force) { return; } @@ -99,7 +95,7 @@ namespace AMDiS { /** \brief * The problem is serialized every tsModulo-th timestep. */ - int tsModulo; + int tsModulo_; /** \brief * Current timestep number.