...
 
Commits (35)
...@@ -17,11 +17,28 @@ endif () ...@@ -17,11 +17,28 @@ endif ()
# some options to control the build process # some options to control the build process
option(ENABLE_PARALLEL_DOMAIN "Use parallel domain decomposition" false) option(ENABLE_PARALLEL_DOMAIN "Use parallel domain decomposition" false)
option(ENABLE_MPI "Compile with MPI compiler and library" false)
option(ENABLE_UMFPACK "Enable support for the UMFPACK solver" true) option(ENABLE_UMFPACK "Enable support for the UMFPACK solver" true)
option(ENABLE_EXTENSIONS "Use extensions for AMDiS" false) option(ENABLE_EXTENSIONS "Use extensions for AMDiS" false)
option(ENABLE_HYPRE "Use HYPRE AMG solver" false) option(ENABLE_HYPRE "Use HYPRE AMG solver" false)
option(ENABLE_PNG "Use png reader/writer" false) option(ENABLE_PNG "Use png reader/writer" false)
option(ENABLE_SEQ_PETSC "Use sequential PETSc solvers" false)
include(CMakeDependentOption)
# additional options for parallel_domain
# {
cmake_dependent_option(ENABLE_ZOLTAN
"Add support for the Parallel Partitioning suite Zoltan" false
"ENABLE_PARALLEL_DOMAIN" false)
cmake_dependent_option(ENABLE_PARALLEL_SOLVERS
"Add some problem dependent solver, e.g. Feti, Navier-Stokes and Cahn-Hilliard" true
"ENABLE_PARALLEL_DOMAIN" false)
cmake_dependent_option(ENABLE_BDDCML
"Add support for the BDDCML library" false
"ENABLE_PARALLEL_DOMAIN" false)
# }
# enable/disable some more features # enable/disable some more features
option(ENABLE_COMPRESSION "Use output compression for vtu and arh files" true) option(ENABLE_COMPRESSION "Use output compression for vtu and arh files" true)
...@@ -33,6 +50,12 @@ mark_as_advanced(ENABLE_REINIT) ...@@ -33,6 +50,12 @@ mark_as_advanced(ENABLE_REINIT)
option(ENABLE_COMPOSITE_FEM "Compile compositeFEM library" true) option(ENABLE_COMPOSITE_FEM "Compile compositeFEM library" true)
mark_as_advanced(ENABLE_COMPOSITE_FEM) mark_as_advanced(ENABLE_COMPOSITE_FEM)
option(ENABLE_OPENMP "Compile with OpenMP flags. (Experimental)" false)
mark_as_advanced(ENABLE_OPENMP)
option(ENABLE_SEQ_PETSC "Use sequential PETSc solvers" false)
mark_as_advanced(ENABLE_SEQ_PETSC)
option(BUILD_SHARED_LIBS "Build all libraries as shared or static, default: shared" true) option(BUILD_SHARED_LIBS "Build all libraries as shared or static, default: shared" true)
mark_as_advanced(BUILD_SHARED_LIBS) mark_as_advanced(BUILD_SHARED_LIBS)
...@@ -46,6 +69,7 @@ endif (MSVC) ...@@ -46,6 +69,7 @@ endif (MSVC)
# parallel of sequential version # parallel of sequential version
if (ENABLE_PARALLEL_DOMAIN) if (ENABLE_PARALLEL_DOMAIN)
set(ENABLE_MPI CACHE BOOL "Compile with MPI compiler and library" FORCE)
set(POSTFIX "-p") set(POSTFIX "-p")
else () else ()
set(POSTFIX "-s") set(POSTFIX "-s")
......
if (ENABLE_PARALLEL_DOMAIN) if (ENABLE_PARALLEL_DOMAIN)
option(ENABLE_ZOLTAN "Add support for the Parallel Partitioning suite Zoltan" false)
option(ENABLE_PARALLEL_SOLVERS "Add some problem dependent solver, e.g. Feti, Navier-Stokes and Cahn-Hilliard" true)
option(ENABLE_BDDCML "Add support for the BDDCML library" false)
mark_as_advanced(ENABLE_PARALLEL_SOLVERS)
mark_as_advanced(ENABLE_BDDCML)
set(PARALLEL_DOMAIN_AMDIS_SRC set(PARALLEL_DOMAIN_AMDIS_SRC
${SOURCE_DIR}/parallel/DofComm.cc ${SOURCE_DIR}/parallel/DofComm.cc
${SOURCE_DIR}/parallel/CheckerPartitioner.cc ${SOURCE_DIR}/parallel/CheckerPartitioner.cc
......
...@@ -12,22 +12,14 @@ macro(enable_mtl4 _FLAGS_ _INC_DIRS_ _LIBS_) ...@@ -12,22 +12,14 @@ macro(enable_mtl4 _FLAGS_ _INC_DIRS_ _LIBS_)
endif (LINK_EXECUTABLE) endif (LINK_EXECUTABLE)
list(APPEND ${_FLAGS_} "-DMTL_ASSERT_FOR_THROW=1") list(APPEND ${_FLAGS_} "-DMTL_ASSERT_FOR_THROW=1")
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
if (ENABLE_CXX11 OR AMDIS_NEED_CXX11) foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL") list(APPEND ${_FLAGS_} "-DMTL_WITH_${feature}")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST}) endforeach ()
list(APPEND ${_FLAGS_} "-DMTL_WITH_${feature}")
endforeach ()
endif ()
if (ENABLE_OPENMP) if (ENABLE_OPENMP)
find_package(OpenMP REQUIRED) find_package(OpenMP REQUIRED)
if (OPENMP_FOUND) list(APPEND ${_FLAGS_} "-DMTL_WITH_OPENMP" "-DHAVE_OPENMP" ${OpenMP_CXX_FLAGS})
list(APPEND ${_FLAGS_} "-DMTL_WITH_OPENMP" ${OpenMP_CXX_FLAGS})
else ()
message(FATAL_ERROR "OpenMP not found")
endif (OPENMP_FOUND)
endif (ENABLE_OPENMP) endif (ENABLE_OPENMP)
endmacro(enable_mtl4) endmacro(enable_mtl4)
set(AMDIS_NEED_CXX11 @ENABLE_CXX11@)
set(AMDIS_NEED_UMFPACK @ENABLE_UMFPACK@) set(AMDIS_NEED_UMFPACK @ENABLE_UMFPACK@)
set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSION@) set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSION@)
set(AMDIS_NEED_EXTENSIONS @ENABLE_EXTENSIONS@) set(AMDIS_NEED_EXTENSIONS @ENABLE_EXTENSIONS@)
...@@ -12,22 +11,23 @@ set(AMDIS_NEED_PNG @ENABLE_PNG@) ...@@ -12,22 +11,23 @@ set(AMDIS_NEED_PNG @ENABLE_PNG@)
set(AMDIS_NEED_SEQ_PETSC @ENABLE_SEQ_PETSC@) set(AMDIS_NEED_SEQ_PETSC @ENABLE_SEQ_PETSC@)
set(BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@) set(BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
set(CMAKE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
add_library(amdis_base INTERFACE) add_library(amdis_base INTERFACE)
add_library(AMDiS ALIAS amdis_base) add_library(AMDiS ALIAS amdis_base)
target_compile_definitions(amdis_base INTERFACE) target_compile_definitions(amdis_base INTERFACE)
if (AMDIS_NEED_CXX11)
target_enable_cxx11(AMDIS_NEED_CXX11 amdis_base INTERFACE) target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE)
if (NOT AMDIS_NEED_CXX11) if (NOT SUPPORTS_CXX14)
message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!") target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE)
endif (NOT AMDIS_NEED_CXX11) endif ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
else () if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0) message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!")
endif (AMDIS_NEED_CXX11) endif ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
# try to detect the AMDiS include directory # try to detect the AMDiS include directory
......
...@@ -23,12 +23,19 @@ add_library(AMDiS::base ALIAS amdis_base) ...@@ -23,12 +23,19 @@ add_library(AMDiS::base ALIAS amdis_base)
target_include_directories(amdis_base INTERFACE ${SOURCE_DIR}) target_include_directories(amdis_base INTERFACE ${SOURCE_DIR})
target_compile_definitions(amdis_base INTERFACE) target_compile_definitions(amdis_base INTERFACE)
target_enable_cxx11(ENABLE_CXX11 amdis_base INTERFACE)
if (ENABLE_CXX11) target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1) if (SUPPORTS_CXX14)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX14=1)
else () else ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0) target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE)
endif (ENABLE_CXX11) endif ()
if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14)
message(FATAL_ERROR "AMDiS needs c++11 support, but the current compiler does not support this feature!")
endif ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
target_enable_mtl4(amdis_base INTERFACE) target_enable_mtl4(amdis_base INTERFACE)
target_enable_boost(amdis_base INTERFACE) target_enable_boost(amdis_base INTERFACE)
...@@ -65,6 +72,7 @@ add_library(amdis ...@@ -65,6 +72,7 @@ add_library(amdis
${SOURCE_DIR}/DOFAdmin.cc ${SOURCE_DIR}/DOFAdmin.cc
${SOURCE_DIR}/DOFIndexed.cc ${SOURCE_DIR}/DOFIndexed.cc
${SOURCE_DIR}/DOFMatrix.cc ${SOURCE_DIR}/DOFMatrix.cc
${SOURCE_DIR}/DOFSerializer.cc
${SOURCE_DIR}/DOFVector.cc ${SOURCE_DIR}/DOFVector.cc
${SOURCE_DIR}/DirichletBC.cc ${SOURCE_DIR}/DirichletBC.cc
${SOURCE_DIR}/DualTraverse.cc ${SOURCE_DIR}/DualTraverse.cc
...@@ -171,6 +179,11 @@ add_library(amdis ...@@ -171,6 +179,11 @@ add_library(amdis
${SOURCE_DIR}/ProblemStatDbg.cc ${SOURCE_DIR}/ProblemStatDbg.cc
) )
if (ENABLE_MPI)
target_enable_mpi(amdis_base INTERFACE)
target_compile_definitions(amdis_base INTERFACE HAVE_MPI=1)
endif (ENABLE_MPI)
include(amdis_parallel) # adds sources to amdis include(amdis_parallel) # adds sources to amdis
include(amdis_extensions) # -> target AMDiS::extensions include(amdis_extensions) # -> target AMDiS::extensions
include(muparser) # -> target muparser include(muparser) # -> target muparser
......
if (ENABLE_PARALLEL_DOMAIN) if (ENABLE_PARALLEL_DOMAIN)
option(ENABLE_ZOLTAN "Add support for the Parallel Partitioning suite Zoltan" false)
option(ENABLE_PARALLEL_SOLVERS "Add some problem dependent solver, e.g. Feti, Navier-Stokes and Cahn-Hilliard" true)
mark_as_advanced(ENABLE_PARALLEL_SOLVERS)
add_library(amdis_parallel INTERFACE) add_library(amdis_parallel INTERFACE)
target_sources(amdis PRIVATE target_sources(amdis PRIVATE
${SOURCE_DIR}/parallel/DofComm.cc ${SOURCE_DIR}/parallel/DofComm.cc
......
...@@ -17,10 +17,8 @@ add_library(muparser STATIC ...@@ -17,10 +17,8 @@ add_library(muparser STATIC
target_include_directories(muparser PUBLIC ${MUPARSER_INCLUDE_DIR}) target_include_directories(muparser PUBLIC ${MUPARSER_INCLUDE_DIR})
set_property(TARGET muparser PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET muparser PROPERTY POSITION_INDEPENDENT_CODE ON)
if (ENABLE_CXX11) target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE)
target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE) target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1)
target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1)
endif (ENABLE_CXX11)
# specify how to install this target: # specify how to install this target:
# ----------------------------------- # -----------------------------------
......
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
macro(target_enable_cxx14 RESULT_VAR _TARGET_ _SCOPE_)
check_cxx_compiler_flag("-std=c++14" COMPILER_SUPPORTS_CXX14_FLAG)
set(CXX14_CODE "
auto f() { return 1; }
int main(){
auto f1 = [](auto const& y) { return y; };
auto y0 = f();
auto y1 = f1(1);
}")
if (COMPILER_SUPPORTS_CXX14_FLAG)
set(CMAKE_REQUIRED_FLAGS "-std=c++14")
check_cxx_source_compiles("${CXX14_CODE}" CXX14_COMPILES_WITH_CXX14_FLAG)
set(CMAKE_REQUIRED_FLAGS "")
endif ()
if (COMPILER_SUPPORTS_CXX14_FLAG AND CXX14_COMPILES_WITH_CXX14_FLAG)
target_compile_options(${_TARGET_} ${_SCOPE_} "-std=c++14")
set(${RESULT_VAR} true CACHE BOOL "Enable C++14 compiler features" FORCE)
else ()
check_cxx_source_compiles("${CXX14_CODE}" CXX14_COMPILES)
if (CXX14_COMPILES)
set(${RESULT_VAR} true CACHE BOOL "Enable C++14 compiler features" FORCE)
else ()
set(${RESULT_VAR} false CACHE BOOL "Enable C++14 compiler features" FORCE)
endif ()
endif ()
endmacro(target_enable_cxx14)
macro(target_enable_cxx11 RESULT_VAR _TARGET_ _SCOPE_) macro(target_enable_cxx11 RESULT_VAR _TARGET_ _SCOPE_)
check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11_FLAG) check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11_FLAG)
......
macro(target_enable_mtl4 _TARGET_ _SCOPE_) macro(target_enable_mtl4 _TARGET_ _SCOPE_)
if (${ARGC} GREATER 2) if (${ARGC} GREATER 2)
set(LINK_EXECUTABLE ON) set(LINK_EXECUTABLE ON)
else () else ()
set(LINK_EXECUTABLE OFF) set(LINK_EXECUTABLE OFF)
endif () endif ()
if (LINK_EXECUTABLE) if (LINK_EXECUTABLE)
target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4) target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4)
else () else ()
target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4) target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4)
endif (LINK_EXECUTABLE) endif (LINK_EXECUTABLE)
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1) target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1)
if (ENABLE_CXX11) set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL") foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
foreach (feature ${CXX_ELEVEN_FEATURE_LIST}) target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature})
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature}) endforeach ()
endforeach ()
endif (ENABLE_CXX11)
if (ENABLE_OPENMP)
find_package(OpenMP REQUIRED)
if (OPENMP_FOUND)
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_OPENMP)
target_compile_options(${_TARGET_} ${_SCOPE_} ${OpenMP_CXX_FLAGS})
else ()
message(FATAL_ERROR "OpenMP not found")
endif (OPENMP_FOUND)
endif (ENABLE_OPENMP)
if (ENABLE_OPENMP)
find_package(OpenMP REQUIRED)
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_OPENMP HAVE_OPENMP)
target_compile_options(${_TARGET_} ${_SCOPE_} ${OpenMP_CXX_FLAGS})
endif (ENABLE_OPENMP)
endmacro(target_enable_mtl4) endmacro(target_enable_mtl4)
...@@ -115,7 +115,7 @@ namespace AMDiS { ...@@ -115,7 +115,7 @@ namespace AMDiS {
Parameters::init(initFileName); Parameters::init(initFileName);
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_OPENMP) || defined(HAVE_MPI)
Parameters::get("parallel->log main rank", Msg::outputMainRank); Parameters::get("parallel->log main rank", Msg::outputMainRank);
#endif #endif
......
...@@ -156,11 +156,8 @@ namespace AMDiS { ...@@ -156,11 +156,8 @@ namespace AMDiS {
rosenbrockMode(false) rosenbrockMode(false)
{ {
init(); init();
char number[5]; for (int i = 0; i < size; i++)
for (int i = 0; i < size; i++) { scalContents[i] = new ScalContent(name + "[" + std::to_string(i) + "]");
sprintf(number, "[%d]", i);
scalContents[i] = new ScalContent(name + std::string(number));
}
} }
/// Destructor. /// Destructor.
......
...@@ -88,7 +88,7 @@ namespace AMDiS { ...@@ -88,7 +88,7 @@ namespace AMDiS {
/// Returns number of managed problems /// Returns number of managed problems
int CouplingIterationInterface::getNumProblems() int CouplingIterationInterface::getNumProblems() const
{ {
size_t num= 0; size_t num= 0;
for (size_t i = 0; i < problems.size(); ++i) for (size_t i = 0; i < problems.size(); ++i)
...@@ -122,7 +122,7 @@ namespace AMDiS { ...@@ -122,7 +122,7 @@ namespace AMDiS {
/// Returns the name of the problem. /// Returns the name of the problem.
std::string CouplingIterationInterface::getName(size_t number) std::string CouplingIterationInterface::getName(size_t number) const
{ {
if (static_cast<size_t>(problems.size()) <= number) if (static_cast<size_t>(problems.size()) <= number)
throw(std::runtime_error("Problem number out of range.")); throw(std::runtime_error("Problem number out of range."));
......
...@@ -61,7 +61,7 @@ namespace AMDiS { ...@@ -61,7 +61,7 @@ namespace AMDiS {
/// Called after each adaption loop iteration. /// Called after each adaption loop iteration.
virtual void endIteration(AdaptInfo *adaptInfo); virtual void endIteration(AdaptInfo *adaptInfo);
virtual int getNumProblems(); virtual int getNumProblems() const;
/// Returns number of managed problems /// Returns number of managed problems
virtual size_t getNumIterationInterfaces() { return problems.size(); } virtual size_t getNumIterationInterfaces() { return problems.size(); }
...@@ -75,8 +75,8 @@ namespace AMDiS { ...@@ -75,8 +75,8 @@ namespace AMDiS {
virtual ProblemIterationInterface *getIterationInterface(size_t number = 0) { return problems[number]; } virtual ProblemIterationInterface *getIterationInterface(size_t number = 0) { return problems[number]; }
/// Returns the name of the problem with the given number. /// Returns the name of the problem with the given number.
virtual std::string getName(size_t number); virtual std::string getName(size_t number) const;
virtual std::string getName() { return getName(0); } virtual std::string getName() const { return getName(0); }
virtual void setSolveProblem(size_t number, bool flag = true) { solveProblem[number] = flag; } virtual void setSolveProblem(size_t number, bool flag = true) { solveProblem[number] = flag; }
virtual void setSolveProblem(std::string name, bool flag = true); virtual void setSolveProblem(std::string name, bool flag = true);
......
...@@ -75,8 +75,7 @@ namespace AMDiS { ...@@ -75,8 +75,7 @@ namespace AMDiS {
virtual void initialize(Flag initFlag, virtual void initialize(Flag initFlag,
ProblemStatSeq *adoptProblem = NULL, ProblemStatSeq *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING) Flag adoptFlag = INIT_NOTHING)
{ FUNCNAME("CouplingProblemStat::initialize()"); {
super::initialize(initFlag - INIT_MESH); super::initialize(initFlag - INIT_MESH);
const Flag DEFAULT_INIT = (INIT_FE_SPACE | INIT_MESH | CREATE_MESH | INIT_SYSTEM | INIT_SOLVER | INIT_ESTIMATOR | INIT_MARKER | INIT_FILEWRITER); const Flag DEFAULT_INIT = (INIT_FE_SPACE | INIT_MESH | CREATE_MESH | INIT_SYSTEM | INIT_SOLVER | INIT_ESTIMATOR | INIT_MARKER | INIT_FILEWRITER);
...@@ -130,7 +129,7 @@ namespace AMDiS { ...@@ -130,7 +129,7 @@ namespace AMDiS {
problems[i]->componentMeshes.resize(nComponents + nAddComponents); problems[i]->componentMeshes.resize(nComponents + nAddComponents);
for (size_t j = 0; j < nComponents + nAddComponents; j++) { for (int j = 0; j < nComponents + nAddComponents; j++) {
// name of the mesh // name of the mesh
std::string meshName(""); std::string meshName("");
Parameters::get(problems[i]->getName() + "->mesh", meshName); Parameters::get(problems[i]->getName() + "->mesh", meshName);
...@@ -186,7 +185,7 @@ namespace AMDiS { ...@@ -186,7 +185,7 @@ namespace AMDiS {
problems[p]->componentSpaces.resize(nComponents + nAddComponents, NULL); problems[p]->componentSpaces.resize(nComponents + nAddComponents, NULL);
problems[p]->traverseInfo.resize(nComponents); problems[p]->traverseInfo.resize(nComponents);
for (size_t i = 0; i < nComponents + nAddComponents; i++) { for (int i = 0; i < nComponents + nAddComponents; i++) {
std::string componentString = "[" + to_string(i) + "]"; std::string componentString = "[" + to_string(i) + "]";
...@@ -335,7 +334,7 @@ namespace AMDiS { ...@@ -335,7 +334,7 @@ namespace AMDiS {
/// Returns number of managed problems /// Returns number of managed problems
virtual int getNumProblems() virtual int getNumProblems() const
{ {
return problems.size(); return problems.size();
} }
...@@ -348,17 +347,35 @@ namespace AMDiS { ...@@ -348,17 +347,35 @@ namespace AMDiS {
{ {
return problems[number]; return problems[number];
} }
virtual ProblemStatType const* getProblem(int number = 0) const
{
return problems[number];
}
/// Returns \ref meshes[i] /// Returns \ref meshes[i]
inline Mesh* getMesh(int number = 0) Mesh* getMesh(int number = 0)
{
return meshes[number];
}
/// Returns \ref meshes[i]
Mesh const* getMesh(int number = 0) const
{ {
return meshes[number]; return meshes[number];
} }
using super::getNumComponents;
using super::getRefinementManager; using super::getRefinementManager;
using super::getCoarseningManager; using super::getCoarseningManager;
using super::getName; using super::getName;
virtual int getNumComponents() const override
{
int num = 0;
for (int i = 0; i < getNumProblems(); ++i)
num += getProblem(i)->getNumComponents();
return num;
}
protected: protected:
/// unqiue mesh-dimension for all problems /// unqiue mesh-dimension for all problems
......
...@@ -215,10 +215,15 @@ namespace AMDiS { ...@@ -215,10 +215,15 @@ namespace AMDiS {
TEST_EXIT(dofIndexed)("no dofIndexed\n"); TEST_EXIT(dofIndexed)("no dofIndexed\n");
if (dofIndexed->getSize() < size) #ifdef _OPENMP
dofIndexed->resize(size); #pragma omp critical (addDOFIndexed)
#endif
dofIndexedList.push_back(dofIndexed); {
if (dofIndexed->getSize() < size)
dofIndexed->resize(size);
dofIndexedList.push_back(dofIndexed);
}
} }
...@@ -226,18 +231,17 @@ namespace AMDiS { ...@@ -226,18 +231,17 @@ namespace AMDiS {
{ {
FUNCNAME("DOFAdmin::removeDOFIndexed()"); FUNCNAME("DOFAdmin::removeDOFIndexed()");
bool removed = false; #ifdef _OPENMP
std::list<DOFIndexedBase*>::iterator it; #pragma omp critical (removeDOFIndexed)
std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); #endif
for (it = dofIndexedList.begin(); it != end; ++it) { {
if (*it == dofIndexed) { auto it = std::find(dofIndexedList.begin(), dofIndexedList.end(), dofIndexed);
dofIndexedList.erase(it); if (it != dofIndexedList.end())
removed = true; dofIndexedList.erase(it);
break; else {
ERROR_EXIT("DOFIndexed not in list!\n");
} }
} }
TEST_EXIT(removed)("DOFIndexed not in list!\n");
} }
...@@ -255,16 +259,17 @@ namespace AMDiS { ...@@ -255,16 +259,17 @@ namespace AMDiS {
{ {
FUNCNAME("DOFAdmin::removeDOFContainer()"); FUNCNAME("DOFAdmin::removeDOFContainer()");
std::list<DOFContainer*>::iterator it; #ifdef _OPENMP
std::list<DOFContainer*>::iterator end = dofContainerList.end(); #pragma omp critical (removeDOFContainer)
for (it = dofContainerList.begin(); it != end; ++it) { #endif
if (*it == cont) { {
dofContainerList.erase(it); auto it = std::find(dofContainerList.begin(), dofContainerList.end(), cont);
return; if (it != dofContainerList.end())
dofContainerList.erase(it);
else {
ERROR_EXIT("Container not in list!\n");
} }
} }
ERROR("Container not in list!\n");
} }
......
...@@ -182,6 +182,12 @@ namespace AMDiS { ...@@ -182,6 +182,12 @@ namespace AMDiS {
return mesh; return mesh;
} }
/// Returns \ref mesh
inline Mesh* getMesh()
{
return mesh;
}
/// Returns \ref dofFree, the array denoting DOFs to be either free or used. /// Returns \ref dofFree, the array denoting DOFs to be either free or used.
inline const std::vector<bool>& getDofFree() const inline const std::vector<bool>& getDofFree() const
{ {
......
...@@ -43,7 +43,7 @@ namespace AMDiS { ...@@ -43,7 +43,7 @@ namespace AMDiS {
DOFMatrix::DOFMatrix() DOFMatrix::DOFMatrix()
: rowFeSpace(NULL), : rowFeSpace(NULL),
colFeSpace(NULL), colFeSpace(NULL),
elementMatrix(3, 3), elementMatrix(0, 0),
nRow(0), nRow(0),
nCol(0), nCol(0),
nnzPerRow(0), nnzPerRow(0),
......
#include "DOFSerializer.h"
#include <algorithm>
#include "DOFVector.h"
#include "Global.h"
#include "Traverse.h"
namespace AMDiS
{
// satre values of DOFVector on all macro elements to internal container
void DOFSerializer::gather(DOFVector<double> const* vec, std::vector<double>& values)
{
std::fill(visited_.begin(), visited_.end(), false);
values.clear();
for (auto* macroEl : mesh_->getMacroElements())
gather(macroEl->getIndex(), vec, values, false);
}
// satre values of DOFVector on macro element `macroIndex` to internal container
void DOFSerializer::gather(int macroIndex, DOFVector<double> const* vec, std::vector<double>& values, bool reset)
{
if (reset) {
std::fill(visited_.begin(), visited_.end(), false);
values.clear();
}
TEST_EXIT(mesh_ == vec->getFeSpace()->getMesh())("Incompatible meshes!\n");
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirstOneMacro(mesh_, macroIndex, -1, Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) {
Element *el = elInfo->getElement();
if (el->isLeaf()) {
gather(VERTEX, elInfo, vec, values);
if (mesh_->getDim() > 1)
gather(EDGE, elInfo, vec, values);
if (mesh_->getDim() == 3)
gather(FACE, elInfo, vec, values);
gather(CENTER, elInfo, vec, values);
}
elInfo = stack.traverseNext(elInfo);
}
}
void DOFSerializer::gather(GeoIndex geo, ElInfo* elInfo, DOFVector<double> const* vec, std::vector<double>& values)
{
int nd;
if ((nd = admin_->getNumberOfDofs(geo))) {
int entities = mesh_->getGeo(geo);
int nd0 = admin_->getNumberOfPreDofs(geo);
int n0 = mesh_->getNode(geo);
for (int n = 0; n < entities; n++) {
for(int d = 0; d < nd; d++) {
DegreeOfFreedom globalDof = elInfo->getElement()->getDof(n0 + n, nd0 + d);
TEST_EXIT(globalDof < visited_.size())("visited container not large enough!\n");
if (!visited_[globalDof]) {
visited_[globalDof] = true;
values.push_back((*vec)[globalDof]);
}
}
}
}
}
// assign stored values to DOFVector, for all macro elements
void DOFSerializer::scatter(std::vector<double> const& values, DOFVector<double>* vec) const
{
std::fill(visited_.begin(), visited_.end(), false);
counter_ = 0u;
for (auto* macroEl : mesh_->getMacroElements())
scatter(macroEl->getIndex(), values, vec, false);
}
// assign stored values to DOFVector, on macroElement with index `macroIndex`
void DOFSerializer::scatter(int macroIndex, std::vector<double> const& values, DOFVector<double>* vec, bool reset) const
{
if (reset) {
std::fill(visited_.begin(), visited_.end(), false);
counter_ = 0u;
}
TEST_EXIT(mesh_ == vec->getFeSpace()->getMesh())("Incompatible meshes!\n");
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirstOneMacro(mesh_, macroIndex, -1, Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) {
Element *el = elInfo->getElement();
if (el->isLeaf()) {
scatter(VERTEX, elInfo, values, vec);
if (mesh_->getDim() > 1)
scatter(EDGE, elInfo, values, vec);
if (mesh_->getDim() == 3)
scatter(FACE, elInfo, values, vec);
scatter(CENTER, elInfo, values, vec);
}
elInfo = stack.traverseNext(elInfo);
}
}
void DOFSerializer::scatter(GeoIndex geo, ElInfo* elInfo, std::vector<double> const& values, DOFVector<double>* vec) const
{
int nd;
if ((nd = admin_->getNumberOfDofs(geo))) {
int entities = mesh_->getGeo(geo);
int nd0 = admin_->getNumberOfPreDofs(geo);
int n0 = mesh_->getNode(geo);
for (int n = 0; n < entities; n++) {
for(int d = 0; d < nd; d++) {
DegreeOfFreedom globalDof = elInfo->getElement()->getDof(n0 + n, nd0 + d);
TEST_EXIT(globalDof < visited_.size())("visited container not large enough!\n");
if (!visited_[globalDof]) {
visited_[globalDof] = true;
TEST_EXIT(counter_ < values.size())("Not enough values in value-container!\n");
(*vec)[globalDof] = values[counter_++];
}
}
}
}
}
} // end namespace AMDiS
/******************************************************************************
*
* AMDiS - Adaptive multidimensional simulations
*
* Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
* Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
*
* Authors:
* Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* This file is part of AMDiS
*
* See also license.opensource.txt in the distribution.
*
******************************************************************************/
/** \file DOFSerializer.h */
#ifndef AMDIS_DOFSERIALIZER_H
#define AMDIS_DOFSERIALIZER_H
#include <vector>
#include <algorithm>
#include "DOFAdmin.h"
#include "ElInfo.h"
#include "Global.h"
#include "Mesh.h"
#include "Traverse.h"
namespace AMDiS
{
// Collect all DOFValues into a std::vector, by traversing the mesh macro-elenment wise
// Can be used to transfer data on macro elements or to store values in a file, e.g. in ARHWriter
class DOFSerializer
{
public:
/// Constructor, stores a pointer to the DOFAdmin. If the number of values to store can be estimated,
/// pass a second argument `numValues`
DOFSerializer(DOFAdmin* admin, std::size_t numValues = 0)
: admin_(admin)
, mesh_(admin->getMesh())
, visited_(admin->getUsedSize(), false)
{}
// satre values of DOFVector on all macro elements to internal container
void gather(DOFVector<double> const* vec, std::vector<double>& values);
// satre values of DOFVector on macro element `macroIndex` to internal container
void gather(int macroIndex, DOFVector<double> const* vec, std::vector<double>& values, bool reset = true);
// assign stored values to DOFVector, for all macro elements
void scatter(std::vector<double> const& values, DOFVector<double>* vec) const;
// assign stored values to DOFVector, on macroElement with index `macroIndex`
void scatter(int macroIndex, std::vector<double> const& values, DOFVector<double>* vec, bool reset = true) const;
protected:
// collect values of one geometry-type
void gather(GeoIndex geo, ElInfo* elInfo, DOFVector<double> const* vec, std::vector<double>& values);
// assign values of one geometry type
void scatter(GeoIndex geo, ElInfo* elInfo, std::vector<double> const& values, DOFVector<double>* vec) const;
protected:
DOFAdmin* admin_;
Mesh* mesh_;
// stored which DOFs were already visited during traversal
mutable std::vector<bool> visited_;
// a counter used during assignment of values. To guarantee the same order as during gather
mutable std::size_t counter_ = 0u;
};
} // end namespace AMDiS
#endif // AMDIS_DOFSERIALIZER_H
...@@ -273,7 +273,7 @@ namespace AMDiS { ...@@ -273,7 +273,7 @@ namespace AMDiS {
template<> template<>
void DOFVector<double>::interpol(DOFVector<double> *source, double factor) void DOFVector<double>::interpol(const DOFVector<double> *source, double factor)
{ {
const FiniteElemSpace *sourceFeSpace = source->getFeSpace(); const FiniteElemSpace *sourceFeSpace = source->getFeSpace();
...@@ -383,7 +383,7 @@ namespace AMDiS { ...@@ -383,7 +383,7 @@ namespace AMDiS {
template<> template<>
void DOFVector<WorldVector<double> >::interpol(DOFVector<WorldVector<double> > *v, void DOFVector<WorldVector<double> >::interpol(const DOFVector<WorldVector<double> > *v,
double factor) double factor)
{ {
FUNCNAME("DOFVector<WorldVector<double> >::interpol()"); FUNCNAME("DOFVector<WorldVector<double> >::interpol()");
......
...@@ -574,7 +574,7 @@ namespace AMDiS { ...@@ -574,7 +574,7 @@ namespace AMDiS {
/// stores these in the DOFVector /// stores these in the DOFVector
void interpol(AbstractFunction<T, WorldVector<double> > *fct); void interpol(AbstractFunction<T, WorldVector<double> > *fct);
void interpol(DOFVector<T> *v, double factor = 1.0); void interpol(const DOFVector<T> *v, double factor = 1.0);
/// Eval DOFVector at given point p. If oldElInfo != NULL the search for /// Eval DOFVector at given point p. If oldElInfo != NULL the search for
......
...@@ -124,8 +124,10 @@ namespace AMDiS { ...@@ -124,8 +124,10 @@ namespace AMDiS {
{ {
this->name = n; this->name = n;
this->feSpace = f; this->feSpace = f;
if (this->feSpace && this->feSpace->getAdmin()) if (this->feSpace && this->feSpace->getAdmin())
(this->feSpace->getAdmin())->addDOFIndexed(this); (this->feSpace->getAdmin())->addDOFIndexed(this);
this->boundaryManager = new BoundaryManager(f); this->boundaryManager = new BoundaryManager(f);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (addToSynch && Parallel::MeshDistributor::globalMeshDistributor != NULL) if (addToSynch && Parallel::MeshDistributor::globalMeshDistributor != NULL)
...@@ -140,6 +142,10 @@ namespace AMDiS { ...@@ -140,6 +142,10 @@ namespace AMDiS {
if ( Parallel::MeshDistributor::globalMeshDistributor != NULL) if ( Parallel::MeshDistributor::globalMeshDistributor != NULL)
Parallel::MeshDistributor::globalMeshDistributor->removeInterchangeVector(this); Parallel::MeshDistributor::globalMeshDistributor->removeInterchangeVector(this);
#endif #endif
#ifdef _OPENMP
#pragma omp critical
#endif
if (this->feSpace && this->feSpace->getAdmin()) if (this->feSpace && this->feSpace->getAdmin())
(this->feSpace->getAdmin())->removeDOFIndexed(this); (this->feSpace->getAdmin())->removeDOFIndexed(this);
......
...@@ -111,6 +111,93 @@ namespace AMDiS { ...@@ -111,6 +111,93 @@ namespace AMDiS {
} }
bool DualTraverse::traverseFirstOneMacro(Mesh *mesh1,
Mesh *mesh2,
int macroIndex,
int level1,
int level2,
Flag flag1,
Flag flag2,
ElInfo **elInfo1,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge)
{
FUNCNAME("DualTraverse::traverseFirst()");
// replace CALL_EL_LEVEL by CALL_MG_LEVEL (covers whole domain)
if (flag1.isSet(Mesh::CALL_EL_LEVEL)) {
flag1 &= ~Mesh::CALL_EL_LEVEL;
flag1 |= Mesh::CALL_MG_LEVEL;
level1_ = level1;
} else {
level1_ = -1;
}
if (flag2.isSet(Mesh::CALL_EL_LEVEL)) {
flag2 &= ~Mesh::CALL_EL_LEVEL;
flag2 |= Mesh::CALL_MG_LEVEL;
level2_ = level2;
} else {
level2_ = -1;
}
// replace CALL_LEAF_EL_LEVEL by CALL_MG_LEVEL (covers whole domain)
if (flag1.isSet(Mesh::CALL_LEAF_EL_LEVEL)) {
flag1 &= ~Mesh::CALL_LEAF_EL_LEVEL;
flag1 |= Mesh::CALL_MG_LEVEL;
level1_ = level1;
callLeafElLevel1_ = true;
} else {
level1_ = -1;
callLeafElLevel1_ = false;
}
if (flag2.isSet(Mesh::CALL_LEAF_EL_LEVEL)) {
flag2 &= ~Mesh::CALL_LEAF_EL_LEVEL;
flag2 |= Mesh::CALL_MG_LEVEL;
level2_ = level2;
callLeafElLevel2_ = true;
} else {
level2_ = -1;
callLeafElLevel2_ = false;
}
// call standard traverse
*elInfo1 = stack1.traverseFirstOneMacro(mesh1, macroIndex, level1, flag1);
while (*elInfo1 != NULL && skipEl1(*elInfo1)) {
*elInfo1 = stack1.traverseNext(*elInfo1);
}
*elInfo2 = stack2.traverseFirstOneMacro(mesh2, macroIndex, level2, flag2);
while (*elInfo2 != NULL && skipEl2(*elInfo2)) {
*elInfo2 = stack2.traverseNext(*elInfo2);
}
// finished ?
if (*elInfo1 == NULL || *elInfo2 == NULL) {
TEST_EXIT(*elInfo1 == *elInfo2)("invalid dual traverse\n");
return false;
}
rest = 1.0;
bool accepted = check(elInfo1, elInfo2, elInfoSmall, elInfoLarge);
// check for non domain covering level traverse
if (!accepted ||
(level1_ != -1 && (*elInfo1)->getLevel() != level1_) ||
(callLeafElLevel1_ && !(*elInfo1)->getElement()->isLeaf()) ||
(level2_ != -1 && (*elInfo2)->getLevel() != level2_) ||
(callLeafElLevel2_ && !(*elInfo2)->getElement()->isLeaf())) {
return traverseNext(elInfo1, elInfo2, elInfoSmall, elInfoLarge);
}
fillSubElInfo(*elInfo1, *elInfo2, *elInfoSmall, *elInfoLarge);
return true;
}
bool DualTraverse::traverseNext(ElInfo **elInfo1, bool DualTraverse::traverseNext(ElInfo **elInfo1,
ElInfo **elInfo2, ElInfo **elInfo2,
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
......
...@@ -78,6 +78,18 @@ namespace AMDiS { ...@@ -78,6 +78,18 @@ namespace AMDiS {
&(dualElInfo.smallElInfo), &(dualElInfo.smallElInfo),
&(dualElInfo.largeElInfo)); &(dualElInfo.largeElInfo));
} }
bool traverseFirstOneMacro(Mesh *mesh1,
Mesh *mesh2,
int macroIndex,
int level1,
int level2,
Flag flag1,
Flag flag2,
ElInfo **elInfo1,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge);
/// Get next ElInfo combination /// Get next ElInfo combination
bool traverseNext(ElInfo **elInfoNext1, bool traverseNext(ElInfo **elInfoNext1,
......
...@@ -161,8 +161,6 @@ namespace AMDiS { ...@@ -161,8 +161,6 @@ namespace AMDiS {
double length = (coord[1][0] - a); double length = (coord[1][0] - a);
int dim = mesh->getDim(); int dim = mesh->getDim();
static DimVec<double> vec(dim, NO_INIT);
TEST_EXIT_DBG(lambda)("lambda must not be NULL\n"); TEST_EXIT_DBG(lambda)("lambda must not be NULL\n");
TEST_EXIT_DBG(dim == 1)("dim!=1\n"); TEST_EXIT_DBG(dim == 1)("dim!=1\n");
TEST_EXIT_DBG(dimOfWorld == dim)("not yet for DIM != DIM_OF_WORLD\n"); TEST_EXIT_DBG(dimOfWorld == dim)("not yet for DIM != DIM_OF_WORLD\n");
......
...@@ -679,7 +679,6 @@ namespace AMDiS { ...@@ -679,7 +679,6 @@ namespace AMDiS {
DimVec<WorldVector<double> > edge(mesh->getDim(), NO_INIT); DimVec<WorldVector<double> > edge(mesh->getDim(), NO_INIT);
WorldVector<double> x; WorldVector<double> x;
static DimVec<double> vec(mesh->getDim(), NO_INIT);
int dim = mesh->getDim(); int dim = mesh->getDim();
...@@ -875,4 +874,4 @@ namespace AMDiS { ...@@ -875,4 +874,4 @@ namespace AMDiS {
{ {
return getSubElemCoordsMat(degree); return getSubElemCoordsMat(degree);
} }
} }
\ No newline at end of file
...@@ -336,8 +336,6 @@ namespace AMDiS { ...@@ -336,8 +336,6 @@ namespace AMDiS {
WorldVector<double> x; WorldVector<double> x;
double x0, det, det0, det1, det2; double x0, det, det0, det1, det2;
static DimVec<double> vec(mesh->getDim(), NO_INIT);
TEST_EXIT_DBG(lambda)("lambda must not be NULL\n"); TEST_EXIT_DBG(lambda)("lambda must not be NULL\n");
int dim = mesh->getDim(); int dim = mesh->getDim();
......
...@@ -204,11 +204,16 @@ namespace AMDiS { ...@@ -204,11 +204,16 @@ namespace AMDiS {
void Quad10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat) void Quad10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{ {
if (firstCall) { if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); #ifdef _OPENMP
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI); #pragma omp critical
basFcts = colFeSpace->getBasisFcts(); #endif
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); {
firstCall = false; const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
} }
int nPoints = quadrature->getNumPoints(); int nPoints = quadrature->getNumPoints();
...@@ -240,11 +245,16 @@ namespace AMDiS { ...@@ -240,11 +245,16 @@ namespace AMDiS {
void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector& vec) void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector& vec)
{ {
if (firstCall) { if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); #ifdef _OPENMP
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI); #pragma omp critical
basFcts = colFeSpace->getBasisFcts(); #endif
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); {
firstCall = false; const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
} }
int nPoints = quadrature->getNumPoints(); int nPoints = quadrature->getNumPoints();
...@@ -280,11 +290,16 @@ namespace AMDiS { ...@@ -280,11 +290,16 @@ namespace AMDiS {
const double *values; const double *values;
if (firstCall) { if (firstCall) {
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(), #ifdef _OPENMP
colFeSpace->getBasisFcts(), #pragma omp critical
quadrature); #endif
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature); {
firstCall = false; q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
} }
const int **nEntries = q10->getNumberEntries(); const int **nEntries = q10->getNumberEntries();
...@@ -362,11 +377,16 @@ namespace AMDiS { ...@@ -362,11 +377,16 @@ namespace AMDiS {
void Quad01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat) void Quad01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{ {
if (firstCall) { if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); #ifdef _OPENMP
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI); #pragma omp critical
basFcts = colFeSpace->getBasisFcts(); #endif
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI); {
firstCall = false; const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI);
firstCall = false;
}
} }
int nPoints = quadrature->getNumPoints(); int nPoints = quadrature->getNumPoints();
...@@ -410,11 +430,16 @@ namespace AMDiS { ...@@ -410,11 +430,16 @@ namespace AMDiS {
const double *values; const double *values;
if (firstCall) { if (firstCall) {
q01 = Q01PsiPhi::provideQ01PsiPhi(rowFeSpace->getBasisFcts(), #ifdef _OPENMP
colFeSpace->getBasisFcts(), #pragma omp critical
quadrature); #endif
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature); {
firstCall = false; q01 = Q01PsiPhi::provideQ01PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
} }
const int **nEntries = q01->getNumberEntries(); const int **nEntries = q01->getNumberEntries();
...@@ -446,11 +471,16 @@ namespace AMDiS { ...@@ -446,11 +471,16 @@ namespace AMDiS {
const double *values; const double *values;
if (firstCall) { if (firstCall) {
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(), #ifdef _OPENMP
colFeSpace->getBasisFcts(), #pragma omp critical
quadrature); #endif
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature); {
firstCall = false; q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
} }
const int *nEntries = q1->getNumberEntries(); const int *nEntries = q1->getNumberEntries();
......
...@@ -32,11 +32,14 @@ ...@@ -32,11 +32,14 @@
#ifdef HAVE_PARALLEL_PETSC #ifdef HAVE_PARALLEL_PETSC
#include "petsc.h" #include "petsc.h"
#endif #endif
#ifdef HAVE_OPENMP
#include <omp.h>
#endif
namespace AMDiS { namespace AMDiS {
const char *funcName = NULL; const char *funcName = NULL;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_OPENMP) || defined(HAVE_MPI)
bool Msg::outputMainRank = true; bool Msg::outputMainRank = true;
#endif #endif
...@@ -129,10 +132,14 @@ namespace AMDiS { ...@@ -129,10 +132,14 @@ namespace AMDiS {
void Msg::print_funcname(const char *funcName) void Msg::print_funcname(const char *funcName)
{ {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)
if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
return; return;
#endif #endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
if (!out) if (!out)
out = &std::cout; out = &std::cout;
...@@ -220,10 +227,14 @@ namespace AMDiS { ...@@ -220,10 +227,14 @@ namespace AMDiS {
const char *file, const char *file,
int line) int line)
{ {
#if defined(HAVE_PARALLEL_DOMAIN_AMDIS) && defined(NDEBUG) #if (defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)) && defined(NDEBUG)
if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
return; return;
#endif #endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
static int old_line = -1; static int old_line = -1;
...@@ -254,9 +265,13 @@ namespace AMDiS { ...@@ -254,9 +265,13 @@ namespace AMDiS {
void Msg::print_warn(const char *format, ...) void Msg::print_warn(const char *format, ...)
{ {
#if defined(HAVE_PARALLEL_DOMAIN_AMDIS) && defined(NDEBUG) #if (defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)) && defined(NDEBUG)
if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
return; return;
#endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif #endif
va_list arg; va_list arg;
char buff[255]; char buff[255];
...@@ -274,10 +289,14 @@ namespace AMDiS { ...@@ -274,10 +289,14 @@ namespace AMDiS {
void Msg::print(const char *format, ...) void Msg::print(const char *format, ...)
{ {
#ifndef SUPPRESS_OUTPUT #ifndef SUPPRESS_OUTPUT
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)
if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
return; return;
#endif #endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
va_list arg; va_list arg;
char buff[255]; char buff[255];
...@@ -298,7 +317,6 @@ namespace AMDiS { ...@@ -298,7 +317,6 @@ namespace AMDiS {
int d = -1; int d = -1;
// get dimension // get dimension
TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n");
Parameters::get("dimension of world",d,0); Parameters::get("dimension of world",d,0);
TEST_EXIT(d > 0)("Cannot initialize dimension!\n"); TEST_EXIT(d > 0)("Cannot initialize dimension!\n");
TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d); TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d);
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)
#include <mpi.h> #include <mpi.h>
#endif #endif
...@@ -131,8 +131,10 @@ namespace AMDiS { ...@@ -131,8 +131,10 @@ namespace AMDiS {
#if SUPPRESS_OUTPUT #if SUPPRESS_OUTPUT
#define PRINT_LINE(stream, line) #define PRINT_LINE(stream, line)
#else #else
#if HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)
#define PRINT_LINE(stream, line) stream << "[" << MPI::COMM_WORLD.Get_rank() << "] " << line #define PRINT_LINE(stream, line) stream << "[" << MPI::COMM_WORLD.Get_rank() << "] " << line
#elif defined(HAVE_OPENMP)
#define PRINT_LINE(stream, line) stream << "[" << omp_get_thread_num() << "] " << line
#else #else
#define PRINT_LINE(stream, line) stream << line #define PRINT_LINE(stream, line) stream << line
#endif #endif
...@@ -331,7 +333,7 @@ namespace AMDiS { ...@@ -331,7 +333,7 @@ namespace AMDiS {
} }
public: public:
#if HAVE_PARALLEL_DOMAIN_AMDIS #if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_OPENMP) || defined(HAVE_MPI)
/// In parallel computations, when this variable is true, only the 0 rank will /// In parallel computations, when this variable is true, only the 0 rank will
/// print messages to the output stream. Error messages and warnings are always /// print messages to the output stream. Error messages and warnings are always
/// printed from all ranks. /// printed from all ranks.
......
...@@ -67,17 +67,13 @@ namespace AMDiS { ...@@ -67,17 +67,13 @@ namespace AMDiS {
} }
} }
Initfile* Initfile::singlett = NULL;
std::set<std::string> Initfile::fn_include_list;
/// initialize singleton object and global parameters
/// initialize singleton object an global parameters
void Initfile::init(std::string in) void Initfile::init(std::string in)
{ {
initIntern(); getIncludeList().clear();
fn_include_list.clear(); singlett().read(in);
singlett->read(in); singlett().getInternalParameters();
singlett->getInternalParameters();
} }
...@@ -85,13 +81,13 @@ namespace AMDiS { ...@@ -85,13 +81,13 @@ namespace AMDiS {
void Initfile::read(std::string fn, bool force) void Initfile::read(std::string fn, bool force)
{ {
// read file if its not parsed already // read file if its not parsed already
if (fn_include_list.find(fn) == fn_include_list.end() || force) { if (getIncludeList().find(fn) == getIncludeList().end() || force) {
std::ifstream inputFile; std::ifstream inputFile;
inputFile.open(fn.c_str(), std::ios::in); inputFile.open(fn.c_str(), std::ios::in);
if (!inputFile.is_open()) if (!inputFile.is_open())
throw runtime_error("init-file '" + fn + "' cannot be opened for reading"); throw runtime_error("init-file '" + fn + "' cannot be opened for reading");
fn_include_list.insert(fn); getIncludeList().insert(fn);
read(inputFile); read(inputFile);
} }
} }
...@@ -233,8 +229,6 @@ namespace AMDiS { ...@@ -233,8 +229,6 @@ namespace AMDiS {
void Initfile::readArgv(std::string parameters, int debugInfo) void Initfile::readArgv(std::string parameters, int debugInfo)
{ {
initIntern();
char seperator = ';'; char seperator = ';';
typedef boost::escaped_list_separator<char> TokenizerFunc; typedef boost::escaped_list_separator<char> TokenizerFunc;
typedef boost::tokenizer<TokenizerFunc> Tokenizer; typedef boost::tokenizer<TokenizerFunc> Tokenizer;
...@@ -286,8 +280,7 @@ namespace AMDiS { ...@@ -286,8 +280,7 @@ namespace AMDiS {
/// print all parameters to std::cout /// print all parameters to std::cout
void Initfile::printParameters() void Initfile::printParameters()
{ {
initIntern(); for (Initfile::iterator it = singlett().begin(); it != singlett().end(); it++)
for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++)
std::cout << (*it).first << " => " << (*it).second << std::endl; std::cout << (*it).first << " => " << (*it).second << std::endl;
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <boost/thread/shared_mutex.hpp> // requires c++14
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
...@@ -130,7 +131,7 @@ namespace AMDiS {