From 0ccef766690c8c328d216455e744316651b71336 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Wed, 14 Oct 2009 15:54:39 +0000 Subject: [PATCH] Work on periodic boundary conditions in parallel computation. --- AMDiS/libtool | 64 ++--- AMDiS/src/AMDiS.h | 6 + AMDiS/src/BoundaryCondition.h | 6 + AMDiS/src/BoundaryManager.cc | 94 +++---- AMDiS/src/BoundaryManager.h | 47 +++- AMDiS/src/DOFMatrix.cc | 48 ++-- AMDiS/src/DOFVector.cc | 2 + AMDiS/src/DataCollector.cc | 3 +- AMDiS/src/ElInfo2d.cc | 7 +- AMDiS/src/InteriorBoundary.cc | 2 +- AMDiS/src/InteriorBoundary.h | 2 +- AMDiS/src/LeafData.h | 3 +- AMDiS/src/MacroReader.cc | 19 +- AMDiS/src/ParallelDomainBase.cc | 470 +++++++++++++++++++++++++------ AMDiS/src/ParallelDomainBase.h | 38 ++- AMDiS/src/ParallelDomainVec.cc | 32 ++- AMDiS/src/ParallelDomainVec.h | 3 + AMDiS/src/PeriodicBC.cc | 110 ++++---- AMDiS/src/PeriodicBC.h | 22 +- AMDiS/src/ProblemVec.cc | 4 - AMDiS/src/RCNeighbourList.cc | 317 ++++++++++----------- AMDiS/src/RefinementManager.cc | 5 +- AMDiS/src/RefinementManager2d.cc | 34 ++- AMDiS/src/VertexVector.cc | 39 ++- AMDiS/src/VertexVector.h | 8 +- AMDiS/src/VtkWriter.cc | 2 + 26 files changed, 879 insertions(+), 508 deletions(-) diff --git a/AMDiS/libtool b/AMDiS/libtool index b24ee23d..4c12058b 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="/bin/sed" +SED="/usr/bin/sed" # Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="/bin/sed -e 1s/^X//" +Xsed="/usr/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 NWRW15: +# Libtool was configured on host deimos101: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -66,12 +66,12 @@ fast_install=yes # The host system. host_alias= -host=i686-pc-linux-gnu +host=x86_64-unknown-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=i686-pc-linux-gnu +build=x86_64-unknown-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -82,13 +82,13 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="gcc" +CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" # Is the compiler the GNU C compiler? with_gcc=yes @@ -97,7 +97,7 @@ with_gcc=yes EGREP="grep -E" # The linker used to build libraries. -LD="/usr/bin/ld" +LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" # Whether we need hard or soft links. LN_S="ln -s" @@ -171,7 +171,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="-static" +link_static_flag="" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -325,10 +325,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=" /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/" +sys_lib_search_path_spec=" /usr/lib64/gcc/x86_64-suse-linux/4.1.2/ /usr/lib/gcc/x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/../lib64/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/ /lib/x86_64-suse-linux/4.1.2/ /lib/../lib64/ /usr/lib/x86_64-suse-linux/4.1.2/ /usr/lib/../lib64/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../ /lib/ /usr/lib/" # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib /usr/lib/qt4/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /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 " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -6760,7 +6760,7 @@ build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` # End: # ### BEGIN LIBTOOL TAG CONFIG: CXX -# Libtool was configured on host NWRW15: +# Libtool was configured on host deimos101: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -6782,12 +6782,12 @@ fast_install=yes # The host system. host_alias= -host=i686-pc-linux-gnu +host=x86_64-unknown-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=i686-pc-linux-gnu +build=x86_64-unknown-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -6798,13 +6798,13 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="g++" +CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpiCC" # Is the compiler the GNU C compiler? with_gcc=yes @@ -6813,7 +6813,7 @@ with_gcc=yes EGREP="grep -E" # The linker used to build libraries. -LD="/usr/bin/ld" +LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" # Whether we need hard or soft links. LN_S="ln -s" @@ -6887,7 +6887,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="-static" +link_static_flag="" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -6942,11 +6942,11 @@ striplib="strip --strip-unneeded" # Dependencies to place before the objects being linked to create a # shared library. -predep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginS.o" +predep_objects="/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" # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o" +postdep_objects="/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" # Dependencies to place before the objects being linked to create a # shared library. @@ -6954,11 +6954,11 @@ predeps="" # Dependencies to place after the objects being linked to create a # shared library. -postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" +postdeps="-lmpi_cxx -lmpi -lopen-rte -lopen-pal -libverbs -lrt -lnuma -ldl -lnsl -lutil -ldl -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path="-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/../../.." +compiler_lib_search_path="-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/../../.." # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -7038,10 +7038,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=" /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/" +sys_lib_search_path_spec=" /usr/lib64/gcc/x86_64-suse-linux/4.1.2/ /usr/lib/gcc/x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/../lib64/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../x86_64-suse-linux/4.1.2/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/ /lib/x86_64-suse-linux/4.1.2/ /lib/../lib64/ /usr/lib/x86_64-suse-linux/4.1.2/ /usr/lib/../lib64/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib/ /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../ /lib/ /usr/lib/" # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib /usr/lib/qt4/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /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 " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -7065,7 +7065,7 @@ include_expsyms="" # ### BEGIN LIBTOOL TAG CONFIG: F77 -# Libtool was configured on host NWRW15: +# Libtool was configured on host deimos101: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -7087,12 +7087,12 @@ fast_install=yes # The host system. host_alias= -host=i686-pc-linux-gnu +host=x86_64-unknown-linux-gnu host_os=linux-gnu # The build system. build_alias= -build=i686-pc-linux-gnu +build=x86_64-unknown-linux-gnu build_os=linux-gnu # An echo program that does not interpret backslashes. @@ -7103,7 +7103,7 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" @@ -7112,13 +7112,13 @@ LTCFLAGS="-g -O2" CC="g77" # Is the compiler the GNU C compiler? -with_gcc=yes +with_gcc= # An ERE matcher. EGREP="grep -E" # The linker used to build libraries. -LD="/usr/bin/ld" +LD="/usr/x86_64-suse-linux/bin/ld -m elf_x86_64" # Whether we need hard or soft links. LN_S="ln -s" @@ -7346,10 +7346,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=" /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/" +sys_lib_search_path_spec=" /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/ /usr/lib/gcc/x86_64-suse-linux/3.3.5/ /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../../x86_64-suse-linux/lib/x86_64-suse-linux/3.3.5/ /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../../x86_64-suse-linux/lib/ /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../x86_64-suse-linux/3.3.5/ /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../ /lib/x86_64-suse-linux/3.3.5/ /lib/ /usr/lib/x86_64-suse-linux/3.3.5/ /usr/lib/" # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/octave-2.9.9 /usr/lib/qt-3.3/lib /usr/lib/qt4/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /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 " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h index 3b43a746..f0d73e1a 100644 --- a/AMDiS/src/AMDiS.h +++ b/AMDiS/src/AMDiS.h @@ -92,4 +92,10 @@ #include "VtkWriter.h" #include "parareal/ProblemBase.h" #include "parareal/AdaptParaReal.h" + +#if HAVE_PARALLEL_DOMAIN_AMDIS +#include "ParallelDomainScal.h" +#include "ParallelDomainVec.h" +#endif + #endif diff --git a/AMDiS/src/BoundaryCondition.h b/AMDiS/src/BoundaryCondition.h index b48e407c..fb7f312b 100644 --- a/AMDiS/src/BoundaryCondition.h +++ b/AMDiS/src/BoundaryCondition.h @@ -118,6 +118,12 @@ namespace AMDiS { return false; } + /// Returns whether the boundary condition is a periodic condition or not. + virtual bool isPeriodic() + { + return false; + } + /** \brief * In some situations it may be required to set Dirichlet boundary conditions, * but not to apply them to the matrix. This is for example the case, if the diff --git a/AMDiS/src/BoundaryManager.cc b/AMDiS/src/BoundaryManager.cc index e29a76c7..0aa2e763 100644 --- a/AMDiS/src/BoundaryManager.cc +++ b/AMDiS/src/BoundaryManager.cc @@ -9,6 +9,9 @@ namespace AMDiS { + std::map<BoundaryType, std::vector<BoundaryCondition*> > + BoundaryManager::globalBoundaryMap; + BoundaryManager::BoundaryManager(const FiniteElemSpace *feSpace) { localBounds.resize(omp_get_overall_max_threads()); @@ -39,8 +42,7 @@ namespace AMDiS { const DOFVectorBase<double> *dv) { double result = 0.0; - std::map<BoundaryType, BoundaryCondition*>::iterator it; - for (it = localBCs.begin(); it != localBCs.end(); ++it) + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) if ((*it).second) result += (*it).second->boundResidual(elInfo, matrix, dv); @@ -55,7 +57,6 @@ namespace AMDiS { Vector<DegreeOfFreedom> &dofVec = dofIndices[omp_get_thread_num()]; const BasisFunction *basisFcts = feSpace->getBasisFcts(); int nBasFcts = basisFcts->getNumber(); - std::map<BoundaryType, BoundaryCondition*>::iterator it; // get boundaries of all DOFs BoundaryType *localBound = localBounds[omp_get_thread_num()]; @@ -65,21 +66,20 @@ namespace AMDiS { basisFcts->getLocalIndicesVec(elInfo->getElement(), feSpace->getAdmin(), &dofVec); // apply non dirichlet boundary conditions - for (it = localBCs.begin(); it != localBCs.end(); ++it) + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) if ((*it).second && !(*it).second->isDirichlet()) (*it).second->fillBoundaryCondition(vec, elInfo, &dofVec[0], localBound, nBasFcts); // apply dirichlet boundary conditions - for (it = localBCs.begin(); it != localBCs.end(); ++it) + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) if ((*it).second && (*it).second->isDirichlet()) (*it).second->fillBoundaryCondition(vec, elInfo, &dofVec[0], localBound, nBasFcts); } } - void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, - DOFMatrix *mat) + void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, DOFMatrix *mat) { if (localBCs.size() <= 0) return; @@ -88,7 +88,6 @@ namespace AMDiS { Vector<DegreeOfFreedom> &dofVec = dofIndices[omp_get_thread_num()]; const BasisFunction *basisFcts = feSpace->getBasisFcts(); int nBasFcts = basisFcts->getNumber(); - std::map<BoundaryType, BoundaryCondition*>::iterator it; // get boundaries of all DOFs BoundaryType *localBound = localBounds[omp_get_thread_num()]; @@ -99,75 +98,60 @@ namespace AMDiS { feSpace->getAdmin(), &dofVec); // apply non dirichlet boundary conditions - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if (!(*it).second->isDirichlet()) - (*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], - localBound, nBasFcts); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && !(*it).second->isDirichlet()) + (*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], + localBound, nBasFcts); // apply dirichlet boundary conditions - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if ((*it).second->isDirichlet()) - (*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], - localBound, nBasFcts); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && (*it).second->isDirichlet()) + (*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], + localBound, nBasFcts); } void BoundaryManager::initMatrix(DOFMatrix *matrix) { - std::map<BoundaryType, BoundaryCondition*>::iterator it; - - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if (!(*it).second->isDirichlet()) - (*it).second->initMatrix(matrix); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && !(*it).second->isDirichlet()) + (*it).second->initMatrix(matrix); - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if ((*it).second->isDirichlet()) - (*it).second->initMatrix(matrix); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && (*it).second->isDirichlet()) + (*it).second->initMatrix(matrix); } void BoundaryManager::exitMatrix(DOFMatrix *matrix) { - std::map<BoundaryType, BoundaryCondition*>::iterator it; - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if (!(*it).second->isDirichlet()) - (*it).second->exitMatrix(matrix); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && !(*it).second->isDirichlet()) + (*it).second->exitMatrix(matrix); - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if ((*it).second->isDirichlet()) - (*it).second->exitMatrix(matrix); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && (*it).second->isDirichlet()) + (*it).second->exitMatrix(matrix); } void BoundaryManager::initVector(DOFVectorBase<double> *vector) { - std::map<BoundaryType, BoundaryCondition*>::iterator it; - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if (!(*it).second->isDirichlet()) - (*it).second->initVector(vector); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && !(*it).second->isDirichlet()) + (*it).second->initVector(vector); - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if ((*it).second->isDirichlet()) - (*it).second->initVector(vector); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && (*it).second->isDirichlet()) + (*it).second->initVector(vector); } void BoundaryManager::exitVector(DOFVectorBase<double> *vector) { - std::map<BoundaryType, BoundaryCondition*>::iterator it; - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if (!(*it).second->isDirichlet()) - (*it).second->exitVector(vector); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && !(*it).second->isDirichlet()) + (*it).second->exitVector(vector); - for (it = localBCs.begin(); it != localBCs.end(); ++it) - if ((*it).second) - if ((*it).second->isDirichlet()) - (*it).second->exitVector(vector); + for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it) + if ((*it).second && (*it).second->isDirichlet()) + (*it).second->exitVector(vector); } } diff --git a/AMDiS/src/BoundaryManager.h b/AMDiS/src/BoundaryManager.h index a027d680..a68aa641 100644 --- a/AMDiS/src/BoundaryManager.h +++ b/AMDiS/src/BoundaryManager.h @@ -30,6 +30,8 @@ namespace AMDiS { + typedef std::map<BoundaryType, BoundaryCondition*> BoundaryIndexMap; + /** * \ingroup Assembler * @@ -50,9 +52,15 @@ namespace AMDiS { /// Adds a local boundary condition to the list of managed conditions. void addBoundaryCondition(BoundaryCondition *localBC) { + FUNCNAME("BoundaryManager::addBoundaryCondition()"); + BoundaryType type = localBC->getBoundaryType(); - TEST_EXIT(localBCs[type] == NULL)("there is already a condition for this type\n"); + TEST_EXIT(localBCs[type] == NULL) + ("There is already a condition for this type.\n"); localBCs[type] = localBC; + + std::vector<BoundaryCondition*>& boundMap = globalBoundaryMap[type]; + boundMap.push_back(localBC); } void initMatrix(DOFMatrix *matrix); @@ -79,8 +87,7 @@ namespace AMDiS { * Calls BoundaryCondition::boundResidual() for each boundary condition in * \ref localBCs. */ - double boundResidual(ElInfo *elInfo, - DOFMatrix *matrix, + double boundResidual(ElInfo *elInfo, DOFMatrix *matrix, const DOFVectorBase<double> *dv); inline BoundaryCondition *getBoundaryCondition(BoundaryType type) @@ -88,19 +95,32 @@ namespace AMDiS { return localBCs[type]; } - const std::map<BoundaryType, BoundaryCondition*>& getBoundaryConditionMap() + const BoundaryIndexMap& getBoundaryConditionMap() { return localBCs; } - void setBoundaryConditionMap(const std::map<BoundaryType, BoundaryCondition*>& bcs) + void setBoundaryConditionMap(const BoundaryIndexMap& bcs) { localBCs = bcs; } + + /** \brief + * Returns true, if there is at least one boundary object with the given boundary + * id, which implements a periodic boundary. + */ + static bool isBoundaryPeriodic(BoundaryType b) + { + for (int i = 0; i < static_cast<int>(globalBoundaryMap[b].size()); i++) + if (globalBoundaryMap[b][i]->isPeriodic()) + return true; + + return false; + } protected: /// Map of managed local boundary conditions. - std::map<BoundaryType, BoundaryCondition*> localBCs; + BoundaryIndexMap localBCs; /// Temporary thread-safe variable for functions fillBoundaryconditions. std::vector<BoundaryType*> localBounds; @@ -113,6 +133,21 @@ namespace AMDiS { * each localBounds value. Is used to free the memory in the destructor. */ int allocatedMemoryLocalBounds; + + /** \brief + * For every boundary id we store here all possible boundary object (although + * it's not clear if it is meaningful to have different boundary conditions on the + * same boundary id). + * + * We have to use this global variable, because the mesh traverse interface does + * not provide more information about traversed boundaries at elements than the + * boundary id. + * + * TODO: Change interface such that mesh traverse returns the boundary objects + * directly and we can remove this global variable. The biggest problem will be + * than serialization and deserialization of the mesh. + */ + static std::map<BoundaryType, std::vector<BoundaryCondition*> > globalBoundaryMap; }; } diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc index 7ea53621..d6606ee8 100644 --- a/AMDiS/src/DOFMatrix.cc +++ b/AMDiS/src/DOFMatrix.cc @@ -30,16 +30,18 @@ namespace AMDiS { inserter(NULL) {} - DOFMatrix::DOFMatrix(const FiniteElemSpace* rowFESpace_, - const FiniteElemSpace* colFESpace_, - std::string name_) - : rowFESpace(rowFESpace_), - colFESpace(colFESpace_), - name(name_), + DOFMatrix::DOFMatrix(const FiniteElemSpace* rowSpace, + const FiniteElemSpace* colSpace, + std::string n) + : rowFESpace(rowSpace), + colFESpace(colSpace), + name(n), coupleMatrix(false), inserter(NULL) { - TEST_EXIT(rowFESpace)("no rowFESpace\n"); + FUNCNAME("DOFMatrix::DOFMatrix()"); + + TEST_EXIT(rowFESpace)("No fe space for row!\n"); if (!colFESpace) colFESpace = rowFESpace; @@ -47,7 +49,7 @@ namespace AMDiS { if (rowFESpace && rowFESpace->getAdmin()) (const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->addDOFIndexed(this); - boundaryManager = new BoundaryManager(rowFESpace_); + boundaryManager = new BoundaryManager(rowFESpace); nRow = rowFESpace->getBasisFcts()->getNumber(); nCol = colFESpace->getBasisFcts()->getNumber(); @@ -61,12 +63,14 @@ namespace AMDiS { DOFMatrix::DOFMatrix(const DOFMatrix& rhs) : name(rhs.name + "copy") { + FUNCNAME("DOFMatrix::DOFMatrix()"); + *this = rhs; if (rowFESpace && rowFESpace->getAdmin()) (const_cast<DOFAdmin*>( rowFESpace->getAdmin()))->addDOFIndexed(this); - TEST_EXIT(rhs.inserter == 0)("Cannot copy during insertion"); - inserter= 0; + TEST_EXIT(rhs.inserter == 0)("Cannot copy during insertion!\n"); + inserter = 0; } DOFMatrix::~DOFMatrix() @@ -87,26 +91,6 @@ namespace AMDiS { if (inserter) inserter->print(); - - /* using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end; - namespace traits= mtl::traits; - typedef base_matrix_type Matrix; - - traits::row<Matrix>::type row(matrix); - traits::col<Matrix>::type col(matrix); - traits::const_value<Matrix>::type value(matrix); - - typedef traits::range_generator<major, Matrix>::type cursor_type; - typedef traits::range_generator<nz, cursor_type>::type icursor_type; - - std::cout.precision(10); - for (cursor_type cursor = begin<major>(matrix), cend = end<major>(matrix); cursor != cend; ++cursor) { - for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) - if (value(*icursor) != 0.0) - std::cout << "(" << row(*icursor) << "," << col(*icursor) << "," << value(*icursor) << ") "; - - std::cout << "\n"; - }*/ } bool DOFMatrix::symmetric() @@ -141,9 +125,9 @@ namespace AMDiS { int non_symmetric = !symmetric(); if (non_symmetric) - MSG("matrix `%s' not symmetric.\n", name.data()); + MSG("Matrix `%s' not symmetric.\n", name.data()); else - MSG("matrix `%s' is symmetric.\n", name.data()); + MSG("Matrix `%s' is symmetric.\n", name.data()); } DOFMatrix& DOFMatrix::operator=(const DOFMatrix& rhs) diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc index c2eb996c..fb0740e0 100644 --- a/AMDiS/src/DOFVector.cc +++ b/AMDiS/src/DOFVector.cc @@ -714,11 +714,13 @@ namespace AMDiS { void DOFVectorDOF::freeDOFContent(DegreeOfFreedom dof) { + /* std::vector<DegreeOfFreedom>::iterator it; std::vector<DegreeOfFreedom>::iterator end = vec.end(); DegreeOfFreedom pos = 0; for (it = vec.begin(); it != end; ++it, ++pos) if (*it == dof) *it = pos; + */ } WorldVector<DOFVector<double>*> *transform(DOFVector<WorldVector<double> > *vec, diff --git a/AMDiS/src/DataCollector.cc b/AMDiS/src/DataCollector.cc index c158402f..4e023542 100644 --- a/AMDiS/src/DataCollector.cc +++ b/AMDiS/src/DataCollector.cc @@ -171,9 +171,8 @@ namespace AMDiS { getElementData()-> getElementData(PERIODIC)); - if (ldp) { + if (ldp) nConnection += dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().size(); - } periodicConnections.push_back(DimVec<bool>(dim, DEFAULT_VALUE, false)); } diff --git a/AMDiS/src/ElInfo2d.cc b/AMDiS/src/ElInfo2d.cc index a486147b..8563f4e1 100644 --- a/AMDiS/src/ElInfo2d.cc +++ b/AMDiS/src/ElInfo2d.cc @@ -276,11 +276,10 @@ namespace AMDiS { fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { - if (elem->isNewCoordSet()) { + if (elem->isNewCoordSet()) coord_[2] = *(elem->getNewCoord()); - } else { - coord_[2].setMidpoint(elInfoOld->coord_[0], elInfoOld->coord_[1]); - } + else + coord_[2].setMidpoint(elInfoOld->coord_[0], elInfoOld->coord_[1]); if (ichild == 0) { coord_[0] = elInfoOld->coord_[2]; diff --git a/AMDiS/src/InteriorBoundary.cc b/AMDiS/src/InteriorBoundary.cc index 3d219649..bf90070e 100644 --- a/AMDiS/src/InteriorBoundary.cc +++ b/AMDiS/src/InteriorBoundary.cc @@ -3,7 +3,7 @@ namespace AMDiS { - AtomicBoundary& InteriorBoundary::getNewAtomicBoundary(int rank) + AtomicBoundary& InteriorBoundary::getNewAtomic(int rank) { boundary[rank].resize(boundary[rank].size() + 1); return boundary[rank][boundary[rank].size() - 1]; diff --git a/AMDiS/src/InteriorBoundary.h b/AMDiS/src/InteriorBoundary.h index 148ccb34..79a48fa4 100644 --- a/AMDiS/src/InteriorBoundary.h +++ b/AMDiS/src/InteriorBoundary.h @@ -80,7 +80,7 @@ namespace AMDiS { public: InteriorBoundary() {} - AtomicBoundary& getNewAtomicBoundary(int rank); + AtomicBoundary& getNewAtomic(int rank); /// Writes this object to a file. void serialize(std::ostream &out); diff --git a/AMDiS/src/LeafData.h b/AMDiS/src/LeafData.h index 84127837..4966318f 100644 --- a/AMDiS/src/LeafData.h +++ b/AMDiS/src/LeafData.h @@ -407,8 +407,9 @@ namespace AMDiS { { if (type == PERIODIC) return true; + return false; - }; + } class PeriodicInfo : public Serializable diff --git a/AMDiS/src/MacroReader.cc b/AMDiS/src/MacroReader.cc index c5e64c2e..9e58ec7a 100644 --- a/AMDiS/src/MacroReader.cc +++ b/AMDiS/src/MacroReader.cc @@ -141,15 +141,8 @@ namespace AMDiS { element2->setElementData(ldp2); } - ldp1->addPeriodicInfo(mode, - boundaryType, - sideEl1, - &periodicCoordsEl1); - - ldp2->addPeriodicInfo(mode, - boundaryType, - sideEl2, - &periodicCoordsEl2); + ldp1->addPeriodicInfo(mode, boundaryType, sideEl1, &periodicCoordsEl1); + ldp2->addPeriodicInfo(mode, boundaryType, sideEl2, &periodicCoordsEl2); if (mode != 0) { VertexVector *associated = mesh->periodicAssociations[boundaryType]; @@ -184,9 +177,7 @@ namespace AMDiS { std::map<BoundaryType, VertexVector*>::iterator assocEnd = mesh->periodicAssociations.end(); - for (assoc = mesh->periodicAssociations.begin(); - assoc != assocEnd; - ++assoc) { + for (assoc = mesh->periodicAssociations.begin(); assoc != assocEnd; ++assoc) { DegreeOfFreedom a = (*(assoc->second))[i]; if (a != i) { @@ -201,9 +192,7 @@ namespace AMDiS { std::map<BoundaryType, VertexVector*>::iterator assoc; std::map<BoundaryType, VertexVector*>::iterator assocEnd = mesh->periodicAssociations.end(); - for (assoc = mesh->periodicAssociations.begin(); - assoc != assocEnd; - ++assoc) { + for (assoc = mesh->periodicAssociations.begin(); assoc != assocEnd; ++assoc) { for (int i = 0; i < mesh->getNumberOfVertices(); i++) { if (i != (*(assoc->second))[i]) diff --git a/AMDiS/src/ParallelDomainBase.cc b/AMDiS/src/ParallelDomainBase.cc index 4733416c..806b26df 100644 --- a/AMDiS/src/ParallelDomainBase.cc +++ b/AMDiS/src/ParallelDomainBase.cc @@ -16,6 +16,7 @@ #include "ProblemStatBase.h" #include "StandardProblemIteration.h" #include "ElementFileWriter.h" +#include "VertexVector.h" #include "petscksp.h" @@ -118,11 +119,13 @@ namespace AMDiS { DbgTestInteriorBoundary(); #endif - // === Reset all DOFAdmins of the mesh. === updateDofAdmins(); + // === === + + createPeriodicMap(); // === Global refinements. === @@ -148,11 +151,44 @@ namespace AMDiS { #if (DEBUG != 0) - DbgTestCommonDofs(true); + // DbgTestCommonDofs(true); #endif nRankRows = nRankDofs * nComponents; nOverallRows = nOverallDOFs * nComponents; + +#if 0 + DOFVector<double> *tmp = new DOFVector<double>(feSpace, "tmp"); + tmp->set(0.0); + if (mpiRank == 0) + VtkWriter::writeFile(tmp, "test0.vtu"); + else + VtkWriter::writeFile(tmp, "test1.vtu"); + + if (mpiRank == 1) { + for (PeriodicDofMap::iterator it = periodicDof.begin(); + it != periodicDof.end(); ++it) { + std::cout << "DOF MAP " << it->first << ": "; + for (std::set<DegreeOfFreedom>::iterator dofit = it->second.begin(); + dofit != it->second.end(); ++dofit) + std::cout << *dofit << " "; + std::cout << std::endl; + + DegreeOfFreedom localdof; + for (DofMapping::iterator dofIt = mapLocalGlobalDOFs.begin(); + dofIt != mapLocalGlobalDOFs.end(); ++dofIt) + if (dofIt->second == it->first) + localdof = dofIt->first; + + WorldVector<double> coords; + mesh->getDofIndexCoords(localdof, feSpace, coords); + coords.print(); + } + } +#endif + + if (mpiRank == 0) + writePartitioningMesh("part.vtu"); } @@ -188,7 +224,7 @@ namespace AMDiS { ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); while (elInfo) { TEST_EXIT(elInfo->getLevel() == 0) - ("Mesh is already refined! This does nor work with parallelization!\n"); + ("Mesh is already refined! This does not work with parallelization!\n"); nMacroElements++; @@ -227,16 +263,57 @@ namespace AMDiS { cols.clear(); values.clear(); - int r = mapLocalGlobalDOFs[*cursor] * dispMult + dispAddRow; + int globalRowDof = mapLocalGlobalDOFs[*cursor]; + bool periodicRow = (periodicDof.count(globalRowDof) > 0); - for (icursor_type icursor = begin<nz>(cursor), - icend = end<nz>(cursor); icursor != icend; ++icursor) + for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); + icursor != icend; ++icursor) { if (value(*icursor) != 0.0) { - cols.push_back(mapLocalGlobalDOFs[col(*icursor)] * dispMult + dispAddCol); - values.push_back(value(*icursor)); + int globalColDof = mapLocalGlobalDOFs[col(*icursor)]; + int colIndex = globalColDof * dispMult + dispAddCol; + + if (periodicRow == false && periodicDof.count(globalColDof) > 0) { + cols.push_back(colIndex); + values.push_back(value(*icursor) * 0.5); + + for (std::set<DegreeOfFreedom>::iterator it = periodicDof[globalColDof].begin(); + it != periodicDof[globalColDof].end(); ++it) { + cols.push_back(*it * dispMult + dispAddCol); + values.push_back(value(*icursor) * 0.5); + } + } else { + cols.push_back(colIndex); + values.push_back(value(*icursor)); + } + } + } + + int rowIndex = globalRowDof * dispMult + dispAddRow; + + if (periodicRow) { + int diagIndex = -1; + + for (int i = 0; i < static_cast<int>(values.size()); i++) { + if (cols[i] != rowIndex) + values[i] *= 0.5; + else + diagIndex = i; + } + + MatSetValues(petscMatrix, 1, &rowIndex, cols.size(), &(cols[0]), &(values[0]), ADD_VALUES); + + if (diagIndex != -1) + values[diagIndex] = 0.0; + + for (std::set<DegreeOfFreedom>::iterator it = periodicDof[globalRowDof].begin(); + it != periodicDof[globalRowDof].end(); ++it) { + int perRowIndex = *it * dispMult + dispAddRow; + MatSetValues(petscMatrix, 1, &perRowIndex, cols.size(), &(cols[0]), &(values[0]), ADD_VALUES); } - MatSetValues(petscMatrix, 1, &r, cols.size(), &(cols[0]), &(values[0]), ADD_VALUES); + } else { + MatSetValues(petscMatrix, 1, &rowIndex, cols.size(), &(cols[0]), &(values[0]), ADD_VALUES); + } } } @@ -246,10 +323,23 @@ namespace AMDiS { { DOFVector<double>::Iterator dofIt(vec, USED_DOFS); for (dofIt.reset(); !dofIt.end(); ++dofIt) { - int index = mapLocalGlobalDOFs[dofIt.getDOFIndex()] * dispMult + dispAdd; - double value = *dofIt; + int globalRow = mapLocalGlobalDOFs[dofIt.getDOFIndex()]; + int index = globalRow * dispMult + dispAdd; + + if (periodicDof.count(globalRow) > 0) { + double value = *dofIt * 0.5; + VecSetValues(petscVec, 1, &index, &value, ADD_VALUES); + + for (std::set<DegreeOfFreedom>::iterator it = periodicDof[globalRow].begin(); + it != periodicDof[globalRow].end(); ++it) { + index = *it * dispMult + dispAdd; + VecSetValues(petscVec, 1, &index, &value, ADD_VALUES); + } - VecSetValues(petscVec, 1, &index, &value, ADD_VALUES); + } else { + double value = *dofIt; + VecSetValues(petscVec, 1, &index, &value, ADD_VALUES); + } } } @@ -476,8 +566,7 @@ namespace AMDiS { TEST_EXIT_DBG(r >= 0 && r < nRankRows)("Should not happen!\n"); - if (c < rstart * nComponents || - c >= rstart * nComponents + nRankRows) + if (c < rstart * nComponents || c >= rstart * nComponents + nRankRows) o_nnz[r]++; else d_nnz[r]++; @@ -788,9 +877,9 @@ namespace AMDiS { (element->getElementData(PARTITION_ED)); if (partitionData && partitionData->getPartitionStatus() == IN) { - if (partitionData->getLevel() == 0) { + if (partitionData->getLevel() == 0) elNum = element->getIndex(); - } + TEST_EXIT_DBG(elNum != -1)("invalid element number\n"); if (element->isLeaf()) { elemWeights[elNum] += 1.0; @@ -824,11 +913,17 @@ namespace AMDiS { { FUNCNAME("ParallelDomainBase::createInteriorBoundaryInfo()"); + // To be general, we have to use elInfo->getBoundary(EDGE/FACE, i) instead of + // elInfo->getBoundar(i). + TEST_EXIT(mesh->getDim() == 2) + ("getBoundary(i) returns always i-th edge, generalize for 3d!\n"); + // === First, create all the information about the interior boundaries. === TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(mesh, -1, - Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH); + ElInfo *elInfo = + stack.traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); while (elInfo) { Element *element = elInfo->getElement(); @@ -844,16 +939,8 @@ namespace AMDiS { dynamic_cast<PartitionElementData*>(elInfo->getNeighbour(i)->getElementData(PARTITION_ED)); if (neighbourPartitionData->getPartitionStatus() == OUT) { - // We have found an element that is at an interior boundary. - - int otherElementRank = partitionVec[elInfo->getNeighbour(i)->getIndex()]; - bool ranksBoundary = (mpiRank > otherElementRank); - - AtomicBoundary& bound = - (ranksBoundary ? - myIntBoundary.getNewAtomicBoundary(otherElementRank) : - otherIntBoundary.getNewAtomicBoundary(otherElementRank)); + AtomicBoundary bound; bound.rankObject.el = element; bound.rankObject.elIndex = element->getIndex(); bound.rankObject.subObjAtBoundary = EDGE; @@ -864,10 +951,24 @@ namespace AMDiS { bound.neighbourObject.elIndex = elInfo->getNeighbour(i)->getIndex(); bound.neighbourObject.subObjAtBoundary = EDGE; bound.neighbourObject.ithObjAtBoundary = elInfo->getSideOfNeighbour(i); - + // i == 2 => getSideOfNeighbour(i) == 2 TEST_EXIT_DBG(i != 2 || elInfo->getSideOfNeighbour(i) == 2) ("Should not happen!\n"); + + int otherElementRank = partitionVec[elInfo->getNeighbour(i)->getIndex()]; + + if (BoundaryManager::isBoundaryPeriodic(elInfo->getBoundary(i))) { + // We have found an element that is at an interior, periodic boundary. + AtomicBoundary& b = periodicBoundary.getNewAtomic(otherElementRank); + b = bound; + } else { + // We have found an element that is at an interior, non-periodic boundary. + AtomicBoundary& b = ((mpiRank > otherElementRank) ? + myIntBoundary.getNewAtomic(otherElementRank) : + otherIntBoundary.getNewAtomic(otherElementRank)); + b = bound; + } } } } @@ -875,15 +976,15 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - // === Once we have this information, we must care about their order. Eventually === // === all the boundaries have to be in the same order on both ranks that share === // === the bounday. === std::vector<int*> sendBuffers, recvBuffers; - MPI::Request request[myIntBoundary.boundary.size() + - otherIntBoundary.boundary.size()]; + MPI::Request request[max(myIntBoundary.boundary.size() + + otherIntBoundary.boundary.size(), + periodicBoundary.boundary.size())]; int requestCounter = 0; for (RankToBoundMap::iterator rankIt = myIntBoundary.boundary.begin(); @@ -943,11 +1044,84 @@ namespace AMDiS { } } - delete [] recvBuffers[i++]; + delete [] recvBuffers[i]; + i++; } for (int i = 0; i < static_cast<int>(sendBuffers.size()); i++) delete [] sendBuffers[i]; + + recvBuffers.clear(); + sendBuffers.clear(); + + + // === Deal with periodic boundaries. === + + requestCounter = 0; + + for (RankToBoundMap::iterator rankIt = periodicBoundary.boundary.begin(); + rankIt != periodicBoundary.boundary.end(); ++rankIt) { + + TEST_EXIT_DBG(rankIt->first != mpiRank) + ("It is no possible to have an interior boundary within a rank partition!\n"); + + if (rankIt->first < mpiRank) { + int nSendInt = rankIt->second.size(); + int* buffer = new int[nSendInt * 2]; + for (int i = 0; i < nSendInt; i++) { + buffer[i * 2] = (rankIt->second)[i].rankObject.elIndex; + buffer[i * 2 + 1] = (rankIt->second)[i].rankObject.ithObjAtBoundary; + } + sendBuffers.push_back(buffer); + + request[requestCounter++] = + mpiComm.Isend(buffer, nSendInt * 2, MPI_INT, rankIt->first, 0); + } else { + int nRecvInt = rankIt->second.size(); + int *buffer = new int[nRecvInt * 2]; + recvBuffers.push_back(buffer); + + request[requestCounter++] = + mpiComm.Irecv(buffer, nRecvInt * 2, MPI_INT, rankIt->first, 0); + } + } + + + MPI::Request::Waitall(requestCounter, request); + + + i = 0; + for (RankToBoundMap::iterator rankIt = periodicBoundary.boundary.begin(); + rankIt != periodicBoundary.boundary.end(); ++rankIt) { + if (rankIt->first > mpiRank) { + + for (int j = 0; j < static_cast<int>(rankIt->second.size()); j++) + if (periodicBoundary.boundary[rankIt->first][j].neighbourObject.elIndex != recvBuffers[i][j * 2] || + periodicBoundary.boundary[rankIt->first][j].neighbourObject.ithObjAtBoundary != recvBuffers[i][j * 2 + 1]) { + int k = j + 1; + + for (; k < static_cast<int>(rankIt->second.size()); k++) + if (periodicBoundary.boundary[rankIt->first][k].neighbourObject.elIndex == recvBuffers[i][j * 2] && + periodicBoundary.boundary[rankIt->first][k].neighbourObject.ithObjAtBoundary == recvBuffers[i][j * 2 + 1]) + break; + + // The element must always be found, because the list is just in another order. + TEST_EXIT_DBG(k < static_cast<int>(rankIt->second.size())) + ("Should never happen!\n"); + + // Swap the current with the found element. + AtomicBoundary tmpBound = (rankIt->second)[k]; + (rankIt->second)[k] = (rankIt->second)[j]; + (rankIt->second)[j] = tmpBound; + } + + delete [] recvBuffers[i]; + i++; + } + } + + for (int i = 0; i < static_cast<int>(sendBuffers.size()); i++) + delete [] sendBuffers[i]; } @@ -983,6 +1157,30 @@ namespace AMDiS { createDofMemberInfo(partitionDOFs, rankDofs, rankAllDofs, boundaryDofs, vertexDof); + // === BEGIN EXP + + DofIndexToBool rankAllDofIndices; + for (DofContainer::iterator dofIt = rankAllDofs.begin(); + dofIt != rankAllDofs.end(); ++dofIt) { + rankAllDofIndices[**dofIt] = true; + } + + for (std::map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); + it != mesh->getPeriodicAssociations().end(); ++it) { + VertexVector *tmp = it->second; + DOFIteratorBase it(const_cast<DOFAdmin*>(tmp->getAdmin()), USED_DOFS); + for (it.reset(); !it.end(); ++it) { + if (!it.isDOFFree()) { + if (!rankAllDofIndices[(*tmp)[it.getDOFIndex()]] && + rankAllDofIndices[it.getDOFIndex()]) + // (*tmp)[it.getDOFIndex()] = -1; + (*tmp)[it.getDOFIndex()] = it.getDOFIndex(); + } + } + } + + // === ENDE EXP + nRankDofs = rankDofs.size(); nOverallDOFs = partitionDOFs.size(); @@ -1095,7 +1293,7 @@ namespace AMDiS { int requestCounter = 0; i = 0; - for (std::map<int, DofIndexMap >::iterator sendIt = sendNewDofs.begin(); + for (std::map<int, DofIndexMap>::iterator sendIt = sendNewDofs.begin(); sendIt != sendNewDofs.end(); ++sendIt, i++) { int nSendDofs = sendIt->second.size() * 2; sendBuffers[i] = new int[nSendDofs]; @@ -1182,6 +1380,23 @@ namespace AMDiS { delete [] recvBuffers[i]; } + // ====== BEGIN TEST + + std::map<int, int> dofIndexMap; + for (DofIndexMap::iterator dofIt = rankDofsNewLocalIndex.begin(); + dofIt != rankDofsNewLocalIndex.end(); ++dofIt) { + dofIndexMap[*(dofIt->first)] = dofIt->second; + } + + for (std::map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); + it != mesh->getPeriodicAssociations().end(); ++it) { + it->second->changeDofIndices(dofIndexMap); + } + + + // ====== ENDE TEST + + // === Create now the local to global index and local to dof index mappings. === createLocalMappings(rankDofsNewLocalIndex, rankOwnedDofsNewLocalIndex, @@ -1239,29 +1454,28 @@ namespace AMDiS { sendDofs.clear(); recvDofs.clear(); - for (RankToBoundMap::iterator it = myIntBoundary.boundary.begin(); - it != myIntBoundary.boundary.end(); ++it) { + for (RankToBoundMap::iterator it = myIntBoundary.boundary.begin(); + it != myIntBoundary.boundary.end(); ++it) { + + DofContainer &dofsToSend = sendDofs[it->first]; + + for (DofContainer::iterator iit = oldSendDofs[it->first].begin(); + iit != oldSendDofs[it->first].end(); ++iit) + if (oldVertexDof[*iit]) + dofsToSend.push_back(*iit); for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); boundIt != it->second.end(); ++boundIt) { - - DofContainer &dofsToSend = sendDofs[it->first]; - - for (DofContainer::iterator iit = oldSendDofs[it->first].begin(); - iit != oldSendDofs[it->first].end(); ++iit) - if (oldVertexDof[*iit]) - dofsToSend.push_back(*iit); - DofContainer dofs; - addAllVertexDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, - dofs); - addAllEdgeDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, - dofs); + addVertexDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs); + addEdgeDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs); for (int i = 0; i < static_cast<int>(dofs.size()); i++) { TEST_EXIT_DBG(find(dofsToSend.begin(), dofsToSend.end(), dofs[i]) == dofsToSend.end()) ("Should not happen!\n"); - dofsToSend.push_back(dofs[i]); + dofsToSend.push_back(dofs[i]); } } } @@ -1270,27 +1484,26 @@ namespace AMDiS { for (RankToBoundMap::iterator it = otherIntBoundary.boundary.begin(); it != otherIntBoundary.boundary.end(); ++it) { - for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); - boundIt != it->second.end(); ++boundIt) { - - DofContainer &dofsToRecv = recvDofs[it->first]; - - for (DofContainer::iterator iit = oldRecvDofs[it->first].begin(); - iit != oldRecvDofs[it->first].end(); ++iit) - if (oldVertexDof[*iit]) { - dofsToRecv.push_back(*iit); + DofContainer &dofsToRecv = recvDofs[it->first]; + + for (DofContainer::iterator iit = oldRecvDofs[it->first].begin(); + iit != oldRecvDofs[it->first].end(); ++iit) + if (oldVertexDof[*iit]) { + dofsToRecv.push_back(*iit); - DofContainer::iterator eraseIt = find(rankDofs.begin(), rankDofs.end(), *iit); - if (eraseIt != rankDofs.end()) - rankDofs.erase(eraseIt); - } + DofContainer::iterator eraseIt = find(rankDofs.begin(), rankDofs.end(), *iit); + if (eraseIt != rankDofs.end()) + rankDofs.erase(eraseIt); + } + for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + boundIt != it->second.end(); ++boundIt) { DofContainer dofs; - addAllEdgeDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, - dofs); - addAllVertexDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, - dofs); + addEdgeDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs); + addVertexDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs); for (int i = static_cast<int>(dofs.size()) - 1; i >= 0; i--) { TEST_EXIT_DBG(find(dofsToRecv.begin(), dofsToRecv.end(), dofs[i]) == dofsToRecv.end()) @@ -1398,7 +1611,6 @@ namespace AMDiS { delete [] recvBuffers[i++]; } - // === Create now the local to global index and local to dof index mappings. === createLocalMappings(rankDofsNewLocalIndex, rankOwnedDofsNewLocalIndex, @@ -1426,31 +1638,52 @@ namespace AMDiS { mapLocalToDofIndex[dofIt->second] = *(dofIt->first); } - void ParallelDomainBase::addAllVertexDOFs(Element *el, int ithEdge, - DofContainer& dofs) + void ParallelDomainBase::addVertexDofs(Element *el, int ithEdge, DofContainer& dofs, + bool parentVertices) { - FUNCNAME("ParallelDomainBase::addAllVertexDOFs()"); + FUNCNAME("ParallelDomainBase::addVertexDofs()"); + + TEST_EXIT_DBG(mesh->getDim() == 2)("Not yet implemented for 3D!\n"); + + if (parentVertices) { + switch (ithEdge) { + case 0: + dofs.push_back(el->getDOF(1)); + dofs.push_back(el->getDOF(2)); + break; + case 1: + dofs.push_back(el->getDOF(0)); + dofs.push_back(el->getDOF(2)); + break; + case 2: + dofs.push_back(el->getDOF(0)); + dofs.push_back(el->getDOF(1)); + break; + default: + ERROR_EXIT("Should never happen!\n"); + } + } switch (ithEdge) { case 0: if (el->getSecondChild() && el->getSecondChild()->getFirstChild()) { - addAllVertexDOFs(el->getSecondChild()->getFirstChild(), 0, dofs); + addVertexDofs(el->getSecondChild()->getFirstChild(), 0, dofs); dofs.push_back(el->getSecondChild()->getFirstChild()->getDOF(2)); - addAllVertexDOFs(el->getSecondChild()->getSecondChild(), 1, dofs); + addVertexDofs(el->getSecondChild()->getSecondChild(), 1, dofs); } break; case 1: if (el->getFirstChild() && el->getFirstChild()->getFirstChild()) { - addAllVertexDOFs(el->getFirstChild()->getFirstChild(), 0, dofs); + addVertexDofs(el->getFirstChild()->getFirstChild(), 0, dofs); dofs.push_back(el->getFirstChild()->getFirstChild()->getDOF(2)); - addAllVertexDOFs(el->getFirstChild()->getSecondChild(), 1, dofs); + addVertexDofs(el->getFirstChild()->getSecondChild(), 1, dofs); } break; case 2: if (el->getFirstChild()) { - addAllVertexDOFs(el->getFirstChild(), 0, dofs); + addVertexDofs(el->getFirstChild(), 0, dofs); dofs.push_back(el->getFirstChild()->getDOF(2)); - addAllVertexDOFs(el->getSecondChild(), 1, dofs); + addVertexDofs(el->getSecondChild(), 1, dofs); } break; default: @@ -1459,32 +1692,33 @@ namespace AMDiS { } - void ParallelDomainBase::addAllEdgeDOFs(Element *el, int ithEdge, - DofContainer& dofs) + void ParallelDomainBase::addEdgeDofs(Element *el, int ithEdge, DofContainer& dofs) { - FUNCNAME("ParallelDomainBase::addAllEdgeDOFs()"); + FUNCNAME("ParallelDomainBase::addEdgeDofs()"); + + TEST_EXIT_DBG(mesh->getDim() == 2)("Not yet implemented for 3D!\n"); bool addThisEdge = false; switch (ithEdge) { case 0: if (el->getSecondChild()) - addAllEdgeDOFs(el->getSecondChild(), 2, dofs); + addEdgeDofs(el->getSecondChild(), 2, dofs); else addThisEdge = true; break; case 1: if (el->getFirstChild()) - addAllEdgeDOFs(el->getFirstChild(), 2, dofs); + addEdgeDofs(el->getFirstChild(), 2, dofs); else addThisEdge = true; break; case 2: if (el->getFirstChild()) { - addAllEdgeDOFs(el->getFirstChild(), 0, dofs); - addAllEdgeDOFs(el->getSecondChild(), 1, dofs); + addEdgeDofs(el->getFirstChild(), 0, dofs); + addEdgeDofs(el->getSecondChild(), 1, dofs); } else { addThisEdge = true; } @@ -1594,6 +1828,76 @@ namespace AMDiS { } + void ParallelDomainBase::createPeriodicMap() + { + FUNCNAME("ParallelDomainBase::createPeriodicMap()"); + + MPI::Request request[periodicBoundary.boundary.size() * 2]; + int requestCounter = 0; + std::vector<int*> sendBuffers, recvBuffers; + + for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); + it != periodicBoundary.boundary.end(); ++it) { + + TEST_EXIT_DBG(it->first != mpiRank) + ("Periodic interior boundary within the rank itself is not possible!\n"); + + DofContainer dofs; + + for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + boundIt != it->second.end(); ++boundIt) { + addVertexDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs, true); + addEdgeDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + dofs); + } + + int *sendbuf = new int[dofs.size()]; + for (int i = 0; i < static_cast<int>(dofs.size()); i++) + sendbuf[i] = mapLocalGlobalDOFs[*(dofs[i])]; + + request[requestCounter++] = + mpiComm.Isend(sendbuf, dofs.size(), MPI_INT, it->first, 0); + + sendBuffers.push_back(sendbuf); + + int *recvbuf = new int[dofs.size()]; + request[requestCounter++] = + mpiComm.Irecv(recvbuf, dofs.size(), MPI_INT, it->first, 0); + + recvBuffers.push_back(recvbuf); + } + + + MPI::Request::Waitall(requestCounter, request); + + + int i = 0; + for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); + it != periodicBoundary.boundary.end(); ++it) { + DofContainer dofs; + + for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + boundIt != it->second.end(); ++boundIt) { + DofContainer tmpdofs; + addEdgeDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + tmpdofs); + addVertexDofs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, + tmpdofs, true); + for (int j = static_cast<int>(tmpdofs.size()) - 1; j >= 0; j--) + dofs.push_back(tmpdofs[j]); + } + + for (int j = 0; j < static_cast<int>(dofs.size()); j++) + periodicDof[mapLocalGlobalDOFs[*(dofs[j])]].insert(recvBuffers[i][j]); + + delete [] sendBuffers[i]; + delete [] recvBuffers[i]; + i++; + } + } + + Flag ParallelDomainBase::oneIteration(AdaptInfo *adaptInfo, Flag toDo) { FUNCNAME("ParallelDomainBase::oneIteration()"); @@ -1799,7 +2103,7 @@ namespace AMDiS { { FUNCNAME("ParallelDomainBase::DbgTestCommonDofs()"); - // Maps to each neighbour rank an array of WorldVectors. This array contain the + // Maps to each neighbour rank an array of WorldVectors. This array contains the // coordinates of all dofs this rank shares on the interior boundary with the // neighbour rank. A rank sends the coordinates to another rank, if it owns the // boundarys dof. diff --git a/AMDiS/src/ParallelDomainBase.h b/AMDiS/src/ParallelDomainBase.h index 6e9ff028..34fbca52 100644 --- a/AMDiS/src/ParallelDomainBase.h +++ b/AMDiS/src/ParallelDomainBase.h @@ -81,6 +81,8 @@ namespace AMDiS { typedef std::map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap; + typedef std::map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap; + public: ParallelDomainBase(ProblemIterationInterface *iterationIF, ProblemTimeInterface *timeIF, @@ -93,7 +95,7 @@ namespace AMDiS { void exitParallelization(AdaptInfo *adaptInfo); - void updateDofAdmins(); + void updateDofAdmins(); /** \brief * Test, if the mesh consists of macro elements only. The mesh partitioning of @@ -212,6 +214,8 @@ namespace AMDiS { void updateLocalGlobalNumbering(int& nRankDOFs, int& nOverallDOFs); + void createPeriodicMap(); + /** \brief * This function create new mappings from local to global indices, * \ref mapLocalGlobalDOFs, and from local to dof indices, \ref mapLocalToDofIndex. @@ -229,9 +233,30 @@ namespace AMDiS { DofIndexMap &rankOwnedDofsNewLocalIndex, DofIndexMap &rankDofsNewGlobalIndex); - void addAllVertexDOFs(Element *el, int ithEdge, DofContainer& dofs); + /** \brief + * Traverses an edge on a given element and all its child elements. All vertex + * dofs alonge this edge are assembled and put together to a list. + * + * \param[in] el Element for the edge traverse. + * \param[in] ithEdge Defines the edge on which all the vertex dofs + * are assembled. + * \param[out] dofs All dofs are put to this dof list. + * \param[in] parentVertices If true, also the two vertices of the parent + * element el are put into the result list. + */ + void addVertexDofs(Element *el, int ithEdge, DofContainer& dofs, + bool parentVertices = false); - void addAllEdgeDOFs(Element *el, int ithEdge, DofContainer& dofs); + /** \brief + * Traverses an edge on a given element and all its child elements. All non vertex + * dofs alonge this edge are assembled and put together to a list. + * + * \param[in] el Element for the edge traverse. + * \param[in] ithEdge Defines the edge on which all the non vertex + * dofs are assembled. + * \param[out] dofs All dofs are put to this dof list. + */ + void addEdgeDofs(Element *el, int ithEdge, DofContainer& dofs); /** \brief * This function traverses the whole mesh, i.e. before it is really partitioned, @@ -456,6 +481,11 @@ namespace AMDiS { */ InteriorBoundary otherIntBoundary; + /** \brief + * + */ + InteriorBoundary periodicBoundary; + /** \brief * This map contains for each rank the list of dofs the current rank must send * to exchange solution dofs at the interior boundaries. @@ -487,6 +517,8 @@ namespace AMDiS { */ DofToBool vertexDof; + PeriodicDofMap periodicDof; + /// Is the index of the first row of the linear system, which is owned by the rank. int rstart; diff --git a/AMDiS/src/ParallelDomainVec.cc b/AMDiS/src/ParallelDomainVec.cc index 12edf33b..6fb80f1a 100644 --- a/AMDiS/src/ParallelDomainVec.cc +++ b/AMDiS/src/ParallelDomainVec.cc @@ -4,6 +4,7 @@ #include "ProblemInstat.h" #include "SystemVector.h" #include "Serializer.h" +#include "BoundaryManager.h" namespace AMDiS { @@ -58,7 +59,7 @@ namespace AMDiS { for (int i = 0; i < nComponents; i++) { for (int j = 0; j < nComponents; j++) if (probVec->getSystemMatrix(i, j)) - probVec->getSystemMatrix(i, j)->setRankDofs(isRankDof); + probVec->getSystemMatrix(i, j)->setRankDofs(isRankDof); TEST_EXIT_DBG(probVec->getRHS()->getDOFVector(i))("No rhs vector!\n"); TEST_EXIT_DBG(probVec->getSolution()->getDOFVector(i))("No solution vector!\n"); @@ -66,6 +67,23 @@ namespace AMDiS { probVec->getRHS()->getDOFVector(i)->setRankDofs(isRankDof); probVec->getSolution()->getDOFVector(i)->setRankDofs(isRankDof); } + + for (int i = 0; i < nComponents; i++) { + for (int j = 0; j < nComponents; j++) + if (probVec->getSystemMatrix(i, j) && probVec->getSystemMatrix(i, j)->getBoundaryManager()) + removeBoundaryCondition(const_cast<BoundaryIndexMap&>(probVec->getSystemMatrix(i, j)->getBoundaryManager()->getBoundaryConditionMap())); + + if (probVec->getSolution()->getDOFVector(i)->getBoundaryManager()) + removeBoundaryCondition(const_cast<BoundaryIndexMap&>(probVec->getSolution()->getDOFVector(i)->getBoundaryManager()->getBoundaryConditionMap())); + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + elInfo->getElement()->deleteElementData(PERIODIC); + elInfo = stack.traverseNext(elInfo); + } + } @@ -91,4 +109,16 @@ namespace AMDiS { #endif } + + void ParallelDomainVec::removeBoundaryCondition(BoundaryIndexMap& boundaryMap) + { + BoundaryIndexMap::iterator it = boundaryMap.begin(); + while (it != boundaryMap.end()) { + if (it->second->isPeriodic()) + boundaryMap.erase(it++); + else + ++it; + } + } + } diff --git a/AMDiS/src/ParallelDomainVec.h b/AMDiS/src/ParallelDomainVec.h index 4d6a7f4f..ef79ce30 100644 --- a/AMDiS/src/ParallelDomainVec.h +++ b/AMDiS/src/ParallelDomainVec.h @@ -24,6 +24,7 @@ #include "ParallelDomainBase.h" #include "ProblemVec.h" +#include "BoundaryManager.h" namespace AMDiS { @@ -60,6 +61,8 @@ namespace AMDiS { /// Starts the solution of the linear system using Petsc. void solve(); + void removeBoundaryCondition(BoundaryIndexMap& boundaryMap); + protected: /// Pointer to the stationary problem. ProblemVec *probVec; diff --git a/AMDiS/src/PeriodicBC.cc b/AMDiS/src/PeriodicBC.cc index a252749d..6e178db4 100644 --- a/AMDiS/src/PeriodicBC.cc +++ b/AMDiS/src/PeriodicBC.cc @@ -9,40 +9,39 @@ namespace AMDiS { - std::vector<PeriodicDOFMapping*> PeriodicDOFMapping::mappings_; + std::vector<PeriodicDOFMapping*> PeriodicDOFMapping::mappings; PeriodicDOFMapping* - PeriodicDOFMapping::providePeriodicDOFMapping(const BasisFunction *basFcts) + PeriodicDOFMapping::providePeriodicDOFMapping(const BasisFunction *fcts) { - std::vector<PeriodicDOFMapping*>::iterator it; - std::vector<PeriodicDOFMapping*>::iterator end = mappings_.end(); - for (it = mappings_.begin(); it != end; ++it) - if ((*it)->basFcts_ == basFcts) + for (std::vector<PeriodicDOFMapping*>::iterator it = mappings.begin(); + it != mappings.end(); ++it) + if ((*it)->basFcts == fcts) return *it; - PeriodicDOFMapping *newMapping = new PeriodicDOFMapping(basFcts); - mappings_.push_back(newMapping); + PeriodicDOFMapping *newMapping = new PeriodicDOFMapping(fcts); + mappings.push_back(newMapping); return newMapping; } - PeriodicDOFMapping::PeriodicDOFMapping(const BasisFunction *basFcts) - : basFcts_(basFcts) + PeriodicDOFMapping::PeriodicDOFMapping(const BasisFunction *fcts) + : basFcts(fcts) { FUNCNAME("PeriodicDOFMapping::PeriodicDOFMapping()"); - TEST_EXIT(basFcts_->getDim() > 1)("dim == 1\n"); - int num = basFcts_->getNumber(); + TEST_EXIT(basFcts->getDim() > 1)("dim == 1\n"); + int nBasFcts = basFcts->getNumber(); DimVec<double> *lambda; - for (int i = 0; i < num; i++) { - lambda = basFcts_->getCoords(i); - indexOfCoords_[*lambda] = i; + for (int i = 0; i < nBasFcts; i++) { + lambda = basFcts->getCoords(i); + indexOfCoords[*lambda] = i; } } PeriodicDOFMapping::~PeriodicDOFMapping() { std::map<DimVec<int>, DegreeOfFreedom*, DimVecLess<int> >::iterator it; - for (it = dofPermutation_.begin(); it != dofPermutation_.end(); ++it) + for (it = dofPermutation.begin(); it != dofPermutation.end(); ++it) if (it->second) delete [] it->second; } @@ -51,11 +50,9 @@ namespace AMDiS { { FUNCNAME("PeriodicDOFMapping::getDOFPermutation()"); - if (dofPermutation_[vertexPermutation] == NULL) { - //MSG("new dof permutation needed\n"); - - int dim = basFcts_->getDim(); - int num = basFcts_->getNumber(); + if (dofPermutation[vertexPermutation] == NULL) { + int dim = basFcts->getDim(); + int nBasFcts = basFcts->getNumber(); int sum = 0; for (int i = 0; i < dim + 1; i++) { sum += i - vertexPermutation[i]; @@ -68,33 +65,32 @@ namespace AMDiS { DimVec<double> *lambda; DimVec<double> newLambda(dim, NO_INIT); - DegreeOfFreedom *mapping = new DegreeOfFreedom[num]; + DegreeOfFreedom *mapping = new DegreeOfFreedom[nBasFcts]; - for (int i = 0; i < num; i++) { - lambda = basFcts_->getCoords(i); + for (int i = 0; i < nBasFcts; i++) { + lambda = basFcts->getCoords(i); for (int j = 0; j < dim + 1; j++) newLambda[vertexPermutation[j]] = (*lambda)[j]; - mapping[i] = indexOfCoords_[newLambda]; + mapping[i] = indexOfCoords[newLambda]; } - dofPermutation_[vertexPermutation] = mapping; + dofPermutation[vertexPermutation] = mapping; } - return dofPermutation_[vertexPermutation]; + return dofPermutation[vertexPermutation]; } - PeriodicBC::PeriodicBC(BoundaryType type, FiniteElemSpace *rowFESpace_) - : BoundaryCondition(type, rowFESpace_, NULL), - masterMatrix_(NULL) + PeriodicBC::PeriodicBC(BoundaryType type, FiniteElemSpace *rowSpace) + : BoundaryCondition(type, rowSpace, NULL), + masterMatrix(NULL) { - if (rowFESpace->getMesh()->getDim() > 1) { - periodicDOFMapping_ = - PeriodicDOFMapping::providePeriodicDOFMapping(rowFESpace_->getBasisFcts()); - } else { - periodicDOFMapping_ = NULL; - } + if (rowFESpace->getMesh()->getDim() > 1) + periodicDOFMapping = + PeriodicDOFMapping::providePeriodicDOFMapping(rowFESpace->getBasisFcts()); + else + periodicDOFMapping = NULL; } PeriodicBC::~PeriodicBC() @@ -104,18 +100,16 @@ namespace AMDiS { { FUNCNAME("PeriodicBC::initMatrix()"); - if (!masterMatrix_) { - masterMatrix_ = matrix; - + if (!masterMatrix) { + masterMatrix = matrix; Mesh *mesh = matrix->getRowFESpace()->getMesh(); - associated = mesh->getPeriodicAssociations()[boundaryType]; TEST_EXIT(associated)("No associations for periodic boundary condition %d!\n", boundaryType); const BasisFunction *basFcts = rowFESpace->getBasisFcts(); - neighIndices_ = new DegreeOfFreedom[basFcts->getNumber()]; + neighIndices = new DegreeOfFreedom[basFcts->getNumber()]; } } @@ -125,40 +119,31 @@ namespace AMDiS { const BoundaryType *localBound, int nBasFcts) { - if (matrix == masterMatrix_) { + if (matrix == masterMatrix) { int dim = rowFESpace->getMesh()->getDim(); if (dim > 1) { DOFAdmin *admin = rowFESpace->getAdmin(); - FixVec<int, WORLD> elFace(dim, NO_INIT); FixVec<int, WORLD> neighFace(dim, NO_INIT); DimVec<int> vertexPermutation(dim, NO_INIT); - const BasisFunction *basFcts = rowFESpace->getBasisFcts(); int num = basFcts->getNumber(); - Element *element = elInfo->getElement(); + DimVec<DegreeOfFreedom> periodicDOFs(dim - 1, NO_INIT); + GeoIndex sideGeoIndex = INDEX_OF_DIM(dim - 1, dim); - DimVec<DegreeOfFreedom> periodicDOFs(dim-1, NO_INIT); - - int vertex, index, side; - - GeoIndex sideGeoIndex = INDEX_OF_DIM(dim-1, dim); - - for (side = 0; side < dim + 1; side++) { + for (int side = 0; side < dim + 1; side++) { if (elInfo->getBoundary(sideGeoIndex, side) == boundaryType) { - for (vertex = 0; vertex < dim; vertex++) { - index = element->getVertexOfPosition(sideGeoIndex, - side, - vertex); + for (int vertex = 0; vertex < dim; vertex++) { + int index = element->getVertexOfPosition(sideGeoIndex, side, vertex); periodicDOFs[vertex] = (*associated)[dofIndices[index]]; } Element *neigh = elInfo->getNeighbour(side); - basFcts->getLocalIndices(neigh, admin, neighIndices_); + basFcts->getLocalIndices(neigh, admin, neighIndices); int oppVertex = 0; for (int i = 0; i < dim + 1; i++) { @@ -182,12 +167,12 @@ namespace AMDiS { // get DOF permutation const DegreeOfFreedom *dofPermutation = - periodicDOFMapping_->getDOFPermutation(vertexPermutation); + periodicDOFMapping->getDOFPermutation(vertexPermutation); // set associated dofs for (int i = 0; i < num; i++) if ((*(basFcts->getCoords(i)))[side] == 0) - (*associated)[dofIndices[i]] = neighIndices_[dofPermutation[i]]; + (*associated)[dofIndices[i]] = neighIndices[dofPermutation[i]]; } } } @@ -200,9 +185,9 @@ namespace AMDiS { TEST_EXIT(matrix)("no matrix\n"); - if (matrix == masterMatrix_) { - delete [] neighIndices_; - masterMatrix_ = NULL; + if (matrix == masterMatrix) { + delete [] neighIndices; + masterMatrix = NULL; } using namespace mtl; @@ -236,7 +221,6 @@ namespace AMDiS { for (vecIt.reset(); !vecIt.end(); ++vecIt) { dof = vecIt.getDOFIndex(); - newDOF = (*associated)[dof]; if (dof < newDOF) { diff --git a/AMDiS/src/PeriodicBC.h b/AMDiS/src/PeriodicBC.h index f0444f16..c58cb8ba 100644 --- a/AMDiS/src/PeriodicBC.h +++ b/AMDiS/src/PeriodicBC.h @@ -60,13 +60,13 @@ namespace AMDiS { const DegreeOfFreedom *getDOFPermutation(const DimVec<int> &vertexPermutation); protected: - const BasisFunction *basFcts_; + const BasisFunction *basFcts; - std::map<DimVec<int>, DegreeOfFreedom*, DimVecLess<int> > dofPermutation_; + std::map<DimVec<int>, DegreeOfFreedom*, DimVecLess<int> > dofPermutation; - std::map<DimVec<double>, int, DimVecLess<double> > indexOfCoords_; + std::map<DimVec<double>, int, DimVecLess<double> > indexOfCoords; - static std::vector<PeriodicDOFMapping*> mappings_; + static std::vector<PeriodicDOFMapping*> mappings; }; @@ -80,7 +80,7 @@ namespace AMDiS { { public: /// Constructor. - PeriodicBC(BoundaryType type, FiniteElemSpace *rowFESpace_); + PeriodicBC(BoundaryType type, FiniteElemSpace *rowFESpace); ~PeriodicBC(); @@ -96,14 +96,20 @@ namespace AMDiS { void exitVector(DOFVectorBase<double>* vector); + /// We are defining periodic boundary conditions, so return always true here. + bool isPeriodic() + { + return true; + } + protected: VertexVector *associated; - PeriodicDOFMapping *periodicDOFMapping_; + PeriodicDOFMapping *periodicDOFMapping; - DegreeOfFreedom *neighIndices_; + DegreeOfFreedom *neighIndices; - DOFMatrix *masterMatrix_; + DOFMatrix *masterMatrix; }; } diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc index 273629f5..7ea4f6ce 100644 --- a/AMDiS/src/ProblemVec.cc +++ b/AMDiS/src/ProblemVec.cc @@ -954,7 +954,6 @@ namespace AMDiS { FUNCNAME("ProblemVec::addPeriodicBC()"); FiniteElemSpace *feSpace = componentSpaces[row]; - PeriodicBC *periodic = new PeriodicBC(type, feSpace); if (systemMatrix && (*systemMatrix)[row][col]) @@ -1027,7 +1026,6 @@ namespace AMDiS { } #endif - // == Traverse mesh (either sequentially or in parallel) and assemble. == @@ -1061,7 +1059,6 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - // == Finally, if we have assembled in parallel, we have to add the thread == // == private matrix and vector to the global one. == @@ -1110,7 +1107,6 @@ namespace AMDiS { delete [] bound; } // pragma omp parallel - } void ProblemVec::assembleOnDifMeshes(FiniteElemSpace *rowFeSpace, diff --git a/AMDiS/src/RCNeighbourList.cc b/AMDiS/src/RCNeighbourList.cc index 9ec42078..862a6df1 100644 --- a/AMDiS/src/RCNeighbourList.cc +++ b/AMDiS/src/RCNeighbourList.cc @@ -14,17 +14,17 @@ namespace AMDiS { - RCNeighbourList::RCNeighbourList(int maxEdgeNeigh) { + RCNeighbourList::RCNeighbourList(int maxEdgeNeigh) + { rclist.resize(maxEdgeNeigh); - for (int i = 0; i < maxEdgeNeigh; i++) { + for (int i = 0; i < maxEdgeNeigh; i++) rclist[i] = new RCListElement; - } } - RCNeighbourList::~RCNeighbourList() { - for (int i = 0; i < static_cast<int>(rclist.size()); i++) { + RCNeighbourList::~RCNeighbourList() + { + for (int i = 0; i < static_cast<int>(rclist.size()); i++) delete rclist[i]; - } } /****************************************************************************/ @@ -39,7 +39,7 @@ namespace AMDiS { for (int i = 0; i < n_neigh; i++) { Element *lel = rclist[i]->el; - if (lel->getMark() >= 0 || lel->isLeaf()) { + if (lel->getMark() >= 0 || lel->isLeaf()) { /****************************************************************************/ /* element must not be coarsend or element is a leaf element, reset the */ /* the coarsening flag on all those elements that have to be coarsend with */ @@ -51,7 +51,7 @@ namespace AMDiS { rclist[j]->el->setMark(0); return false; - } else if (lel->getFirstChild()->getMark() >= 0 || + } else if (lel->getFirstChild()->getMark() >= 0 || lel->getSecondChild()->getMark() >= 0) { /****************************************************************************/ @@ -64,8 +64,8 @@ namespace AMDiS { rclist[j]->el->setMark(0); return false; - } else if (!lel->getFirstChild()->isLeaf() || - !lel->getSecondChild()->isLeaf()) { + } else if (!lel->getFirstChild()->isLeaf() || + !lel->getSecondChild()->isLeaf()) { /****************************************************************************/ /* one of the element's children is not a leaf element; */ /* element may be coarsend after coarsening one of the children; try again */ @@ -78,18 +78,15 @@ namespace AMDiS { /* either one element is a macro element or we can coarsen the patch */ /****************************************************************************/ if (rclist[i]->flag == 0) { - - std::deque<MacroElement*>::const_iterator mel; - Mesh* coarse_mesh = coarseningManager->getMesh(); + std::deque<MacroElement*>::const_iterator mel; // set in Mesh::coarsen() for (mel = coarse_mesh->firstMacroElement(); - mel!=coarse_mesh->endOfMacroElements(); - mel++) + mel!=coarse_mesh->endOfMacroElements(); ++mel) if ((*mel)->getElement() == lel) break; - TEST_EXIT(mel!=coarse_mesh->endOfMacroElements()) + TEST_EXIT(mel != coarse_mesh->endOfMacroElements()) ("incompatible coarsening patch found\n"); } } @@ -103,19 +100,19 @@ namespace AMDiS { { FUNCNAME("RCNeighbourList::getNeighOnPatch()"); - int j, k, dir; - Element *el, *neigh; - for (int i = 0; i < n_neigh; i++) { - el = rclist[i]->el; + Element *el = rclist[i]->el; + Element *neigh = NULL; rclist[i]->no = i; - for (dir = 0; dir < 2; dir++) { - for (j = 0; j < n_neigh; j++) { + for (int dir = 0; dir < 2; dir++) { + int j = 0; + for (; j < n_neigh; j++) { if ((neigh = rclist[j]->el) == el) continue; - for (k = 0; k < 2; k++) { + int k = 0; + for (; k < 2; k++) { if (neigh->getDOF(2+k) == el->getDOF(3-dir)) { rclist[i]->neigh[dir] = rclist[j]; rclist[i]->oppVertex[dir] = 3-k; @@ -138,197 +135,166 @@ namespace AMDiS { void RCNeighbourList::addDOFParent(int elIndex, DegreeOfFreedom* dof) // 3d { Element *el = rclist[elIndex]->el; - RCListElement *neighbour; - int node; - + RCListElement *neighbour = NULL; Mesh *coarse_mesh = coarseningManager->getMesh(); RCListElement *coarse_list = rclist[elIndex]; - if (coarse_mesh->getNumberOfDOFs(EDGE)) - { - node = coarse_mesh->getNode(EDGE); - - /****************************************************************************/ - /* set the dof in the coarsening edge */ - /****************************************************************************/ + if (coarse_mesh->getNumberOfDOFs(EDGE)) { + int node = coarse_mesh->getNode(EDGE); - el->setDOF(node, dof); - - /****************************************************************************/ - /* and now those handed on by the children */ - /****************************************************************************/ - - el->setDOF(node+1, const_cast<int*>( el->getFirstChild()->getDOF(node))); - el->setDOF(node+2, const_cast<int*>( el->getFirstChild()->getDOF(node+1))); - el->setDOF(node+5, const_cast<int*>( el->getFirstChild()->getDOF(node+3))); - - if (coarse_list->elType) - { - el->setDOF(node+3, const_cast<int*>( el->getSecondChild()->getDOF(node))); - el->setDOF(node+4, const_cast<int*>( el->getSecondChild()->getDOF(node+1))); - } - else - { - el->setDOF(node+3, const_cast<int*>( el->getSecondChild()->getDOF(node+1))); - el->setDOF(node+4, const_cast<int*>( el->getSecondChild()->getDOF(node))); - } + /****************************************************************************/ + /* set the dof in the coarsening edge */ + /****************************************************************************/ + + el->setDOF(node, dof); + + /****************************************************************************/ + /* and now those handed on by the children */ + /****************************************************************************/ + + el->setDOF(node + 1, const_cast<int*>( el->getFirstChild()->getDOF(node))); + el->setDOF(node + 2, const_cast<int*>( el->getFirstChild()->getDOF(node + 1))); + el->setDOF(node + 5, const_cast<int*>( el->getFirstChild()->getDOF(node + 3))); + + if (coarse_list->elType) { + el->setDOF(node + 3, const_cast<int*>( el->getSecondChild()->getDOF(node))); + el->setDOF(node + 4, const_cast<int*>( el->getSecondChild()->getDOF(node + 1))); + } else { + el->setDOF(node + 3, const_cast<int*>( el->getSecondChild()->getDOF(node + 1))); + el->setDOF(node + 4, const_cast<int*>( el->getSecondChild()->getDOF(node))); } + } - if (coarse_mesh->getNumberOfDOFs(FACE)) - { - node = coarse_mesh->getNode(FACE); - /****************************************************************************/ - /* dof's at the faces within the patch: add new dof's if it is a boundary */ - /* face or neighbour is an element behind this element in the corsen list */ - /****************************************************************************/ - - neighbour = coarse_list->neigh[0]; - if ((!neighbour) || (neighbour > coarse_list)) - { - if (!el->getDOF(node+2)) - { - el->setDOF(node+2, const_cast<int*>( coarse_mesh->getDOF(FACE))); /* face 2 */ - if (neighbour) - neighbour->el->setDOF(node+coarse_list->oppVertex[0], - const_cast<int*>( el->getDOF(node+2))); - } - } - neighbour = coarse_list->neigh[1]; - if ((!neighbour) || (neighbour > coarse_list)) - { - if (!el->getDOF(node+3)) - { - el->setDOF(node+3, const_cast<int*>( coarse_mesh->getDOF(FACE))); /* face 3 */ - if (neighbour) - neighbour->el->setDOF(node+coarse_list->oppVertex[1], - const_cast<int*>( el->getDOF(node+3))); - } - } - /****************************************************************************/ - /* and now those handed on by the children */ - /****************************************************************************/ - - el->setDOF(node, const_cast<int*>( el->getSecondChild()->getDOF(node+3))); - el->setDOF(node+1, const_cast<int*>( el->getFirstChild()->getDOF(node+3))); + if (coarse_mesh->getNumberOfDOFs(FACE)) { + int node = coarse_mesh->getNode(FACE); + /****************************************************************************/ + /* dof's at the faces within the patch: add new dof's if it is a boundary */ + /* face or neighbour is an element behind this element in the corsen list */ + /****************************************************************************/ + + neighbour = coarse_list->neigh[0]; + if (!neighbour || neighbour > coarse_list) { + if (!el->getDOF(node + 2)) { + // face 2 + el->setDOF(node + 2, const_cast<int*>(coarse_mesh->getDOF(FACE))); + if (neighbour) + neighbour->el->setDOF(node + coarse_list->oppVertex[0], + const_cast<int*>(el->getDOF(node + 2))); + } } - - if (coarse_mesh->getNumberOfDOFs(CENTER)) - { - node = coarse_mesh->getNode(CENTER); - if (!el->getDOF(node)) - el->setDOF(node, const_cast<int*>( coarse_mesh->getDOF(CENTER))); + + neighbour = coarse_list->neigh[1]; + if (!neighbour || neighbour > coarse_list) { + if (!el->getDOF(node + 3)) { + // face 3 + el->setDOF(node + 3, const_cast<int*>(coarse_mesh->getDOF(FACE))); + if (neighbour) + neighbour->el->setDOF(node + coarse_list->oppVertex[1], + const_cast<int*>(el->getDOF(node + 3))); + } } - return; + /****************************************************************************/ + /* and now those handed on by the children */ + /****************************************************************************/ + + el->setDOF(node, const_cast<int*>(el->getSecondChild()->getDOF(node + 3))); + el->setDOF(node + 1, const_cast<int*>(el->getFirstChild()->getDOF(node + 3))); + } + + if (coarse_mesh->getNumberOfDOFs(CENTER)) { + int node = coarse_mesh->getNode(CENTER); + if (!el->getDOF(node)) + el->setDOF(node, const_cast<int*>(coarse_mesh->getDOF(CENTER))); + } } void RCNeighbourList::addDOFParents(int n_neigh) // 2d { - int i, node; - Mesh *coarse_mesh = coarseningManager->getMesh(); - if (coarse_mesh->getNumberOfDOFs(EDGE)) - { - node = coarse_mesh->getNode(EDGE); - - /****************************************************************************/ - /* get dofs on the boundary of the coarsening patch from the children */ - /****************************************************************************/ - for (i = 0; i < n_neigh; i++) - { - rclist[i]->el-> - setDOF(node, const_cast<int*>( rclist[i]->el->getSecondChild()->getDOF(node+2))); - rclist[i]->el-> - setDOF(node+1, const_cast<int*>( rclist[i]->el->getFirstChild()->getDOF(node+2))); - } - } - - if (coarse_mesh->getNumberOfDOFs(CENTER)) - { - int node = coarse_mesh->getNode(CENTER); - - /****************************************************************************/ - /* get new dof on parents at the barycenter */ - /****************************************************************************/ - for (i = 0; i < n_neigh; i++) - { - if (!rclist[i]->el->getDOF(node)) - rclist[i]->el->setDOF(node, const_cast<int*>( coarse_mesh->getDOF(CENTER))); - } + if (coarse_mesh->getNumberOfDOFs(EDGE)) { + int node = coarse_mesh->getNode(EDGE); + + /****************************************************************************/ + /* get dofs on the boundary of the coarsening patch from the children */ + /****************************************************************************/ + for (int i = 0; i < n_neigh; i++) { + rclist[i]->el->setDOF(node, const_cast<int*>(rclist[i]->el->getSecondChild()->getDOF(node + 2))); + rclist[i]->el->setDOF(node + 1, const_cast<int*>(rclist[i]->el->getFirstChild()->getDOF(node + 2))); } + } - return; + if (coarse_mesh->getNumberOfDOFs(CENTER)) { + int node = coarse_mesh->getNode(CENTER); + + /****************************************************************************/ + /* get new dof on parents at the barycenter */ + /****************************************************************************/ + for (int i = 0; i < n_neigh; i++) + if (!rclist[i]->el->getDOF(node)) + rclist[i]->el->setDOF(node, const_cast<int*>(coarse_mesh->getDOF(CENTER))); + } } void RCNeighbourList::removeDOFParents(int n_neigh) { - int i, j, node; Mesh *mesh = rclist[0]->el->getMesh(); int edges = mesh->getGeo(EDGE); - if (mesh->getNumberOfDOFs(EDGE)) - { - node = mesh->getNode(EDGE); + if (mesh->getNumberOfDOFs(EDGE)) { + int node = mesh->getNode(EDGE); - for (i = 0; i < n_neigh; i++) - { - for (j = 0; j < edges; j++) - rclist[i]->el->setDOF(node+j, NULL); - } - } + for (int i = 0; i < n_neigh; i++) + for (int j = 0; j < edges; j++) + rclist[i]->el->setDOF(node + j, NULL); + } - if (mesh->getNumberOfDOFs(CENTER)) - { - node = mesh->getNode(CENTER); - for (i = 0; i < n_neigh; i++) - { - mesh->freeDOF(const_cast<int*>( rclist[i]->el->getDOF(node)), CENTER); - rclist[i]->el->setDOF(node, NULL); - } + if (mesh->getNumberOfDOFs(CENTER)) { + int node = mesh->getNode(CENTER); + for (int i = 0; i < n_neigh; i++) { + mesh->freeDOF(const_cast<int*>(rclist[i]->el->getDOF(node)), CENTER); + rclist[i]->el->setDOF(node, NULL); } + } } void RCNeighbourList::removeDOFParent(int index) { Tetrahedron *el = dynamic_cast<Tetrahedron*>(rclist[index]->el); - RCListElement *neigh; - int j, node; Mesh *mesh = el->getMesh(); int edges = mesh->getGeo(EDGE); int faces = mesh->getGeo(FACE); - if (mesh->getNumberOfDOFs(EDGE)) - { - node = mesh->getNode(EDGE); - for (j = 0; j < edges; j++) - el->setDOF(node+j, NULL); - } - - if (mesh->getNumberOfDOFs(FACE)) - { - node = mesh->getNode(FACE); - - neigh = rclist[index]->neigh[0]; - if ((!neigh) || (neigh > rclist[index])) - mesh->freeDOF(const_cast<int*>( el->getDOF(node+2)), FACE); /* face 2 */ + if (mesh->getNumberOfDOFs(EDGE)) { + int node = mesh->getNode(EDGE); + for (int j = 0; j < edges; j++) + el->setDOF(node + j, NULL); + } - neigh = rclist[index]->neigh[1]; - if ((!neigh) || (neigh > rclist[index])) - mesh->freeDOF(const_cast<int*>( el->getDOF(node+3)), FACE); /* face 3 */ + if (mesh->getNumberOfDOFs(FACE)) { + int node = mesh->getNode(FACE); + RCListElement *neigh = rclist[index]->neigh[0]; - for (j = 0; j < faces; j++) - el->setDOF(node+j, NULL); - } + // face 2 + if (!neigh || neigh > rclist[index]) + mesh->freeDOF(const_cast<int*>(el->getDOF(node + 2)), FACE); + + neigh = rclist[index]->neigh[1]; + // face 3 + if (!neigh || neigh > rclist[index]) + mesh->freeDOF(const_cast<int*>(el->getDOF(node + 3)), FACE); + + for (int j = 0; j < faces; j++) + el->setDOF(node + j, NULL); + } - if (mesh->getNumberOfDOFs(CENTER)) - { - node = mesh->getNode(CENTER); - mesh->freeDOF(const_cast<int*>( el->getDOF(node)), CENTER); - el->setDOF(node, NULL); - } - return; + if (mesh->getNumberOfDOFs(CENTER)) { + int node = mesh->getNode(CENTER); + mesh->freeDOF(const_cast<int*>(el->getDOF(node)), CENTER); + el->setDOF(node, NULL); + } } RCNeighbourList *RCNeighbourList::periodicSplit(DegreeOfFreedom *edge[2], @@ -388,9 +354,8 @@ namespace AMDiS { count++; } - for (int i = 0; i < *n_neigh_periodic; i++) { + for (int i = 0; i < *n_neigh_periodic; i++) periodicList->rclist[i]->no = i; - } return periodicList; } diff --git a/AMDiS/src/RefinementManager.cc b/AMDiS/src/RefinementManager.cc index 0dc3649f..02c072cd 100644 --- a/AMDiS/src/RefinementManager.cc +++ b/AMDiS/src/RefinementManager.cc @@ -67,9 +67,8 @@ namespace AMDiS { } } - if (newCoords) { - setNewCoords(); // call of sub-class method - } + if (newCoords) + setNewCoords(); // call of sub-class method delete stack; diff --git a/AMDiS/src/RefinementManager2d.cc b/AMDiS/src/RefinementManager2d.cc index 668151c0..3b9db073 100644 --- a/AMDiS/src/RefinementManager2d.cc +++ b/AMDiS/src/RefinementManager2d.cc @@ -19,11 +19,17 @@ namespace AMDiS { { FUNCNAME("RefinementManager::refineFunction()"); +// if (MPI::COMM_WORLD.Get_rank() == 0) +// std::cout << "IN EL = " << el_info->getElement()->getIndex() << std::endl; + bool bound = false; DegreeOfFreedom *edge[2]; RCNeighbourList* refineList = new RCNeighbourList(2); if (el_info->getElement()->getMark() <= 0) { +// if (MPI::COMM_WORLD.Get_rank() == 0) +// std::cout << "RETURN!" << std::endl; + delete refineList; // Element may not be refined. @@ -84,16 +90,22 @@ namespace AMDiS { firstNewDOF = newDOF; if (lastNewDOF != -1) { + int i = 0; for (it = mesh->getPeriodicAssociations().begin(); it != end; ++it) { +// if (MPI::COMM_WORLD.Get_rank() == 0) +// std::cout << "i = " << i++ << std::endl; + if (it->second) { +// if (MPI::COMM_WORLD.Get_rank() == 0) +// std::cout << "*: " << newDOF << " " << lastNewDOF << std::endl; + if (((*(it->second))[edge[0][0]] == last_edge[0][0] && (*(it->second))[edge[1][0]] == last_edge[1][0]) || ((*(it->second))[edge[0][0]] == last_edge[1][0] && - (*(it->second))[edge[1][0]] == last_edge[0][0])) - { - (*(it->second))[lastNewDOF] = newDOF; - (*(it->second))[newDOF] = lastNewDOF; - } + (*(it->second))[edge[1][0]] == last_edge[0][0])) { + (*(it->second))[lastNewDOF] = newDOF; + (*(it->second))[newDOF] = lastNewDOF; + } } } } @@ -112,11 +124,13 @@ namespace AMDiS { if (((*(it->second))[first_edge[0][0]] == last_edge[0][0] && (*(it->second))[first_edge[1][0]] == last_edge[1][0]) || ((*(it->second))[first_edge[0][0]] == last_edge[1][0] && - (*(it->second))[first_edge[1][0]] == last_edge[0][0])) - { - (*(it->second))[lastNewDOF] = firstNewDOF; - (*(it->second))[firstNewDOF] = lastNewDOF; - } + (*(it->second))[first_edge[1][0]] == last_edge[0][0])) { +// if (MPI::COMM_WORLD.Get_rank() == 0) +// std::cout << "**: " << newDOF << " " << lastNewDOF << std::endl; + + (*(it->second))[lastNewDOF] = firstNewDOF; + (*(it->second))[firstNewDOF] = lastNewDOF; + } } } } diff --git a/AMDiS/src/VertexVector.cc b/AMDiS/src/VertexVector.cc index 919458be..4f17a8ec 100644 --- a/AMDiS/src/VertexVector.cc +++ b/AMDiS/src/VertexVector.cc @@ -4,12 +4,12 @@ namespace AMDiS { - VertexVector::VertexVector(const DOFAdmin *admin_, std::string name_) + VertexVector::VertexVector(const DOFAdmin *a, std::string n) : DOFVectorDOF() { - name = name_; + name = n; feSpace = NULL; - admin = admin_; + admin = a; const_cast<DOFAdmin*>(admin)->addDOFIndexed(this); const_cast<DOFAdmin*>(admin)->addDOFContainer(this); } @@ -23,9 +23,36 @@ namespace AMDiS { void VertexVector::set(DegreeOfFreedom val) { DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); - for(it.reset(); !it.end(); ++it) { - if(!it.isDOFFree()) operator[](it.getDOFIndex()) = val; - } + for (it.reset(); !it.end(); ++it) + if (!it.isDOFFree()) + operator[](it.getDOFIndex()) = val; } + void VertexVector::print() + { + DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); + for (it.reset(); !it.end(); ++it) + if (!it.isDOFFree()) + std::cout << "DOF " << it.getDOFIndex() << " -> " + << operator[](it.getDOFIndex()) << "\n"; + } + + void VertexVector::changeDofIndices(std::map<int, int>& dofIndexMap) + { + FUNCNAME("VertexVector::changedofIndices()"); + + std::vector<DegreeOfFreedom> tmp(vec.size()); + for (int i = 0; i < static_cast<int>(tmp.size()); i++) + tmp[i] = i; + + for (std::map<int, int>::iterator it = dofIndexMap.begin(); + it != dofIndexMap.end(); ++it) + if (vec[it->first] == -1) + tmp[it->second] = -1; + else + tmp[it->second] = dofIndexMap[vec[it->first]]; + + vec = tmp; + } + } diff --git a/AMDiS/src/VertexVector.h b/AMDiS/src/VertexVector.h index 6601f692..f44a587e 100644 --- a/AMDiS/src/VertexVector.h +++ b/AMDiS/src/VertexVector.h @@ -17,7 +17,7 @@ namespace AMDiS { {} }; - VertexVector(const DOFAdmin *admin_, std::string name_); + VertexVector(const DOFAdmin *admin, std::string name); ~VertexVector(); @@ -40,10 +40,14 @@ namespace AMDiS { { DOFContainer::compressDOFContainer(size, newDOF); int totalSize = getAdmin()->getSize(); - for(int i = size; i < totalSize; i++) + for (int i = size; i < totalSize; i++) vec[i] = i; } + void changeDofIndices(std::map<int, int>& dofIndexMap); + + void print(); + protected: const DOFAdmin *admin; }; diff --git a/AMDiS/src/VtkWriter.cc b/AMDiS/src/VtkWriter.cc index 0230281f..9937dae8 100644 --- a/AMDiS/src/VtkWriter.cc +++ b/AMDiS/src/VtkWriter.cc @@ -16,6 +16,8 @@ namespace AMDiS { int VtkWriter::writeFile(std::string name) { + FUNCNAME("VtkWriter::writeFile()"); + #ifdef HAVE_BOOST boost::iostreams::filtering_ostream file; -- GitLab