...
 
Commits (35)
......@@ -17,11 +17,28 @@ endif ()
# some options to control the build process
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_EXTENSIONS "Use extensions for AMDiS" false)
option(ENABLE_HYPRE "Use HYPRE AMG solver" 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
option(ENABLE_COMPRESSION "Use output compression for vtu and arh files" true)
......@@ -33,6 +50,12 @@ mark_as_advanced(ENABLE_REINIT)
option(ENABLE_COMPOSITE_FEM "Compile compositeFEM library" true)
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)
mark_as_advanced(BUILD_SHARED_LIBS)
......@@ -46,6 +69,7 @@ endif (MSVC)
# parallel of sequential version
if (ENABLE_PARALLEL_DOMAIN)
set(ENABLE_MPI CACHE BOOL "Compile with MPI compiler and library" FORCE)
set(POSTFIX "-p")
else ()
set(POSTFIX "-s")
......
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
${SOURCE_DIR}/parallel/DofComm.cc
${SOURCE_DIR}/parallel/CheckerPartitioner.cc
......
......@@ -12,22 +12,14 @@ macro(enable_mtl4 _FLAGS_ _INC_DIRS_ _LIBS_)
endif (LINK_EXECUTABLE)
list(APPEND ${_FLAGS_} "-DMTL_ASSERT_FOR_THROW=1")
if (ENABLE_CXX11 OR AMDIS_NEED_CXX11)
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
list(APPEND ${_FLAGS_} "-DMTL_WITH_${feature}")
endforeach ()
endif ()
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
list(APPEND ${_FLAGS_} "-DMTL_WITH_${feature}")
endforeach ()
if (ENABLE_OPENMP)
find_package(OpenMP REQUIRED)
if (OPENMP_FOUND)
list(APPEND ${_FLAGS_} "-DMTL_WITH_OPENMP" ${OpenMP_CXX_FLAGS})
else ()
message(FATAL_ERROR "OpenMP not found")
endif (OPENMP_FOUND)
list(APPEND ${_FLAGS_} "-DMTL_WITH_OPENMP" "-DHAVE_OPENMP" ${OpenMP_CXX_FLAGS})
endif (ENABLE_OPENMP)
endmacro(enable_mtl4)
set(AMDIS_NEED_CXX11 @ENABLE_CXX11@)
set(AMDIS_NEED_UMFPACK @ENABLE_UMFPACK@)
set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSION@)
set(AMDIS_NEED_EXTENSIONS @ENABLE_EXTENSIONS@)
......@@ -12,22 +11,23 @@ set(AMDIS_NEED_PNG @ENABLE_PNG@)
set(AMDIS_NEED_SEQ_PETSC @ENABLE_SEQ_PETSC@)
set(BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
set(CMAKE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
add_library(amdis_base INTERFACE)
add_library(AMDiS ALIAS amdis_base)
target_compile_definitions(amdis_base INTERFACE)
if (AMDIS_NEED_CXX11)
target_enable_cxx11(AMDIS_NEED_CXX11 amdis_base INTERFACE)
if (NOT AMDIS_NEED_CXX11)
message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!")
endif (NOT AMDIS_NEED_CXX11)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
else ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0)
endif (AMDIS_NEED_CXX11)
target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE)
if (NOT SUPPORTS_CXX14)
target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE)
endif ()
if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14)
message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!")
endif ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
# try to detect the AMDiS include directory
......
......@@ -23,12 +23,19 @@ add_library(AMDiS::base ALIAS amdis_base)
target_include_directories(amdis_base INTERFACE ${SOURCE_DIR})
target_compile_definitions(amdis_base INTERFACE)
target_enable_cxx11(ENABLE_CXX11 amdis_base INTERFACE)
if (ENABLE_CXX11)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1)
target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE)
if (SUPPORTS_CXX14)
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX14=1)
else ()
target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0)
endif (ENABLE_CXX11)
target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE)
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_boost(amdis_base INTERFACE)
......@@ -65,6 +72,7 @@ add_library(amdis
${SOURCE_DIR}/DOFAdmin.cc
${SOURCE_DIR}/DOFIndexed.cc
${SOURCE_DIR}/DOFMatrix.cc
${SOURCE_DIR}/DOFSerializer.cc
${SOURCE_DIR}/DOFVector.cc
${SOURCE_DIR}/DirichletBC.cc
${SOURCE_DIR}/DualTraverse.cc
......@@ -171,6 +179,11 @@ add_library(amdis
${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_extensions) # -> target AMDiS::extensions
include(muparser) # -> target muparser
......
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)
target_sources(amdis PRIVATE
${SOURCE_DIR}/parallel/DofComm.cc
......
......@@ -17,10 +17,8 @@ add_library(muparser STATIC
target_include_directories(muparser PUBLIC ${MUPARSER_INCLUDE_DIR})
set_property(TARGET muparser PROPERTY POSITION_INDEPENDENT_CODE ON)
if (ENABLE_CXX11)
target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE)
target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1)
endif (ENABLE_CXX11)
target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE)
target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1)
# specify how to install this target:
# -----------------------------------
......
include(CheckCXXCompilerFlag)
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_)
check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11_FLAG)
......
macro(target_enable_mtl4 _TARGET_ _SCOPE_)
if (${ARGC} GREATER 2)
set(LINK_EXECUTABLE ON)
else ()
set(LINK_EXECUTABLE OFF)
endif ()
if (${ARGC} GREATER 2)
set(LINK_EXECUTABLE ON)
else ()
set(LINK_EXECUTABLE OFF)
endif ()
if (LINK_EXECUTABLE)
target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4)
else ()
target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4)
endif (LINK_EXECUTABLE)
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1)
if (LINK_EXECUTABLE)
target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4)
else ()
target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4)
endif (LINK_EXECUTABLE)
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1)
if (ENABLE_CXX11)
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature})
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)
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature})
endforeach ()
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)
......@@ -115,7 +115,7 @@ namespace AMDiS {
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);
#endif
......
......@@ -156,11 +156,8 @@ namespace AMDiS {
rosenbrockMode(false)
{
init();
char number[5];
for (int i = 0; i < size; i++) {
sprintf(number, "[%d]", i);
scalContents[i] = new ScalContent(name + std::string(number));
}
for (int i = 0; i < size; i++)
scalContents[i] = new ScalContent(name + "[" + std::to_string(i) + "]");
}
/// Destructor.
......
......@@ -88,7 +88,7 @@ namespace AMDiS {
/// Returns number of managed problems
int CouplingIterationInterface::getNumProblems()
int CouplingIterationInterface::getNumProblems() const
{
size_t num= 0;
for (size_t i = 0; i < problems.size(); ++i)
......@@ -122,7 +122,7 @@ namespace AMDiS {
/// 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)
throw(std::runtime_error("Problem number out of range."));
......
......@@ -61,7 +61,7 @@ namespace AMDiS {
/// Called after each adaption loop iteration.
virtual void endIteration(AdaptInfo *adaptInfo);
virtual int getNumProblems();
virtual int getNumProblems() const;
/// Returns number of managed problems
virtual size_t getNumIterationInterfaces() { return problems.size(); }
......@@ -75,8 +75,8 @@ namespace AMDiS {
virtual ProblemIterationInterface *getIterationInterface(size_t number = 0) { return problems[number]; }
/// Returns the name of the problem with the given number.
virtual std::string getName(size_t number);
virtual std::string getName() { return getName(0); }
virtual std::string getName(size_t number) const;
virtual std::string getName() const { return getName(0); }
virtual void setSolveProblem(size_t number, bool flag = true) { solveProblem[number] = flag; }
virtual void setSolveProblem(std::string name, bool flag = true);
......
......@@ -75,8 +75,7 @@ namespace AMDiS {
virtual void initialize(Flag initFlag,
ProblemStatSeq *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING)
{ FUNCNAME("CouplingProblemStat::initialize()");
{
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);
......@@ -130,7 +129,7 @@ namespace AMDiS {
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
std::string meshName("");
Parameters::get(problems[i]->getName() + "->mesh", meshName);
......@@ -186,7 +185,7 @@ namespace AMDiS {
problems[p]->componentSpaces.resize(nComponents + nAddComponents, NULL);
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) + "]";
......@@ -335,7 +334,7 @@ namespace AMDiS {
/// Returns number of managed problems
virtual int getNumProblems()
virtual int getNumProblems() const
{
return problems.size();
}
......@@ -348,17 +347,35 @@ namespace AMDiS {
{
return problems[number];
}
virtual ProblemStatType const* getProblem(int number = 0) const
{
return problems[number];
}
/// 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];
}
using super::getNumComponents;
using super::getRefinementManager;
using super::getCoarseningManager;
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:
/// unqiue mesh-dimension for all problems
......
......@@ -215,10 +215,15 @@ namespace AMDiS {
TEST_EXIT(dofIndexed)("no dofIndexed\n");
if (dofIndexed->getSize() < size)
dofIndexed->resize(size);
dofIndexedList.push_back(dofIndexed);
#ifdef _OPENMP
#pragma omp critical (addDOFIndexed)
#endif
{
if (dofIndexed->getSize() < size)
dofIndexed->resize(size);
dofIndexedList.push_back(dofIndexed);
}
}
......@@ -226,18 +231,17 @@ namespace AMDiS {
{
FUNCNAME("DOFAdmin::removeDOFIndexed()");
bool removed = false;
std::list<DOFIndexedBase*>::iterator it;
std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end();
for (it = dofIndexedList.begin(); it != end; ++it) {
if (*it == dofIndexed) {
dofIndexedList.erase(it);
removed = true;
break;
#ifdef _OPENMP
#pragma omp critical (removeDOFIndexed)
#endif
{
auto it = std::find(dofIndexedList.begin(), dofIndexedList.end(), dofIndexed);
if (it != dofIndexedList.end())
dofIndexedList.erase(it);
else {
ERROR_EXIT("DOFIndexed not in list!\n");
}
}
TEST_EXIT(removed)("DOFIndexed not in list!\n");
}
......@@ -255,16 +259,17 @@ namespace AMDiS {
{
FUNCNAME("DOFAdmin::removeDOFContainer()");
std::list<DOFContainer*>::iterator it;
std::list<DOFContainer*>::iterator end = dofContainerList.end();
for (it = dofContainerList.begin(); it != end; ++it) {
if (*it == cont) {
dofContainerList.erase(it);
return;
#ifdef _OPENMP
#pragma omp critical (removeDOFContainer)
#endif
{
auto it = std::find(dofContainerList.begin(), dofContainerList.end(), cont);
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 {
return mesh;
}
/// Returns \ref mesh
inline Mesh* getMesh()
{
return mesh;
}
/// Returns \ref dofFree, the array denoting DOFs to be either free or used.
inline const std::vector<bool>& getDofFree() const
{
......
......@@ -43,7 +43,7 @@ namespace AMDiS {
DOFMatrix::DOFMatrix()
: rowFeSpace(NULL),
colFeSpace(NULL),
elementMatrix(3, 3),
elementMatrix(0, 0),
nRow(0),
nCol(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 {
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();
......@@ -383,7 +383,7 @@ namespace AMDiS {
template<>
void DOFVector<WorldVector<double> >::interpol(DOFVector<WorldVector<double> > *v,
void DOFVector<WorldVector<double> >::interpol(const DOFVector<WorldVector<double> > *v,
double factor)
{
FUNCNAME("DOFVector<WorldVector<double> >::interpol()");
......
......@@ -574,7 +574,7 @@ namespace AMDiS {
/// stores these in the DOFVector
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
......
......@@ -124,8 +124,10 @@ namespace AMDiS {
{
this->name = n;
this->feSpace = f;
if (this->feSpace && this->feSpace->getAdmin())
(this->feSpace->getAdmin())->addDOFIndexed(this);
this->boundaryManager = new BoundaryManager(f);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (addToSynch && Parallel::MeshDistributor::globalMeshDistributor != NULL)
......@@ -140,6 +142,10 @@ namespace AMDiS {
if ( Parallel::MeshDistributor::globalMeshDistributor != NULL)
Parallel::MeshDistributor::globalMeshDistributor->removeInterchangeVector(this);
#endif
#ifdef _OPENMP
#pragma omp critical
#endif
if (this->feSpace && this->feSpace->getAdmin())
(this->feSpace->getAdmin())->removeDOFIndexed(this);
......
......@@ -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,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
......
......@@ -78,6 +78,18 @@ namespace AMDiS {
&(dualElInfo.smallElInfo),
&(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
bool traverseNext(ElInfo **elInfoNext1,
......
......@@ -161,8 +161,6 @@ namespace AMDiS {
double length = (coord[1][0] - a);
int dim = mesh->getDim();
static DimVec<double> vec(dim, NO_INIT);
TEST_EXIT_DBG(lambda)("lambda must not be NULL\n");
TEST_EXIT_DBG(dim == 1)("dim!=1\n");
TEST_EXIT_DBG(dimOfWorld == dim)("not yet for DIM != DIM_OF_WORLD\n");
......
......@@ -679,7 +679,6 @@ namespace AMDiS {
DimVec<WorldVector<double> > edge(mesh->getDim(), NO_INIT);
WorldVector<double> x;
static DimVec<double> vec(mesh->getDim(), NO_INIT);
int dim = mesh->getDim();
......@@ -875,4 +874,4 @@ namespace AMDiS {
{
return getSubElemCoordsMat(degree);
}
}
\ No newline at end of file
}
......@@ -336,8 +336,6 @@ namespace AMDiS {
WorldVector<double> x;
double x0, det, det0, det1, det2;
static DimVec<double> vec(mesh->getDim(), NO_INIT);
TEST_EXIT_DBG(lambda)("lambda must not be NULL\n");
int dim = mesh->getDim();
......
......@@ -204,11 +204,16 @@ namespace AMDiS {
void Quad10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{
if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
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();
......@@ -240,11 +245,16 @@ namespace AMDiS {
void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector& vec)
{
if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
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();
......@@ -280,11 +290,16 @@ namespace AMDiS {
const double *values;
if (firstCall) {
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
const int **nEntries = q10->getNumberEntries();
......@@ -362,11 +377,16 @@ namespace AMDiS {
void Quad01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{
if (firstCall) {
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI);
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
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();
......@@ -410,11 +430,16 @@ namespace AMDiS {
const double *values;
if (firstCall) {
q01 = Q01PsiPhi::provideQ01PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
q01 = Q01PsiPhi::provideQ01PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
const int **nEntries = q01->getNumberEntries();
......@@ -446,11 +471,16 @@ namespace AMDiS {
const double *values;
if (firstCall) {
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
#ifdef _OPENMP
#pragma omp critical
#endif
{
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
const int *nEntries = q1->getNumberEntries();
......
......@@ -32,11 +32,14 @@
#ifdef HAVE_PARALLEL_PETSC
#include "petsc.h"
#endif
#ifdef HAVE_OPENMP
#include <omp.h>
#endif
namespace AMDiS {
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;
#endif
......@@ -129,10 +132,14 @@ namespace AMDiS {
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)
return;
#endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
if (!out)
out = &std::cout;
......@@ -220,10 +227,14 @@ namespace AMDiS {
const char *file,
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)
return;
#endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
static int old_line = -1;
......@@ -254,9 +265,13 @@ namespace AMDiS {
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)
return;
#endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
va_list arg;
char buff[255];
......@@ -274,10 +289,14 @@ namespace AMDiS {
void Msg::print(const char *format, ...)
{
#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)
return;
#endif
#ifdef HAVE_OPENMP
if (outputMainRank && omp_get_thread_num() != 0)
return;
#endif
va_list arg;
char buff[255];
......@@ -298,7 +317,6 @@ namespace AMDiS {
int d = -1;
// get dimension
TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n");
Parameters::get("dimension of world",d,0);
TEST_EXIT(d > 0)("Cannot initialize dimension!\n");
TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d);
......
......@@ -53,7 +53,7 @@
#include <unistd.h>
#endif
#if HAVE_PARALLEL_DOMAIN_AMDIS
#if defined(HAVE_PARALLEL_DOMAIN_AMDIS) || defined(HAVE_MPI)
#include <mpi.h>
#endif
......@@ -131,8 +131,10 @@ namespace AMDiS {
#if SUPPRESS_OUTPUT
#define PRINT_LINE(stream, line)
#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
#elif defined(HAVE_OPENMP)
#define PRINT_LINE(stream, line) stream << "[" << omp_get_thread_num() << "] " << line
#else
#define PRINT_LINE(stream, line) stream << line
#endif
......@@ -331,7 +333,7 @@ namespace AMDiS {
}
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
/// print messages to the output stream. Error messages and warnings are always
/// printed from all ranks.
......
......@@ -67,17 +67,13 @@ namespace AMDiS {
}
}
Initfile* Initfile::singlett = NULL;
std::set<std::string> Initfile::fn_include_list;
/// initialize singleton object an global parameters
/// initialize singleton object and global parameters
void Initfile::init(std::string in)
{
initIntern();
fn_include_list.clear();
singlett->read(in);
singlett->getInternalParameters();
getIncludeList().clear();
singlett().read(in);
singlett().getInternalParameters();
}
......@@ -85,13 +81,13 @@ namespace AMDiS {
void Initfile::read(std::string fn, bool force)
{
// 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;
inputFile.open(fn.c_str(), std::ios::in);
if (!inputFile.is_open())
throw runtime_error("init-file '" + fn + "' cannot be opened for reading");
fn_include_list.insert(fn);
getIncludeList().insert(fn);
read(inputFile);
}
}
......@@ -233,8 +229,6 @@ namespace AMDiS {
void Initfile::readArgv(std::string parameters, int debugInfo)
{
initIntern();
char seperator = ';';
typedef boost::escaped_list_separator<char> TokenizerFunc;
typedef boost::tokenizer<TokenizerFunc> Tokenizer;
......@@ -286,8 +280,7 @@ namespace AMDiS {
/// print all parameters to std::cout
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;
}
......
......@@ -37,6 +37,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/thread/shared_mutex.hpp> // requires c++14
#include <boost/type_traits.hpp>
......@@ -130,7 +131,7 @@ namespace AMDiS {
/// convert string to string
inline void convert(const std::string valStr, std::string& value)
inline void convert(const std::string& valStr, std::string& value)
{
value = trim(valStr);
}
......@@ -144,7 +145,7 @@ namespace AMDiS {
boost::mpl::not_< boost::is_enum<T> > >,
void
>::type
convert(const std::string valStr, T& value)
convert(const std::string& valStr, T& value)
{
using boost::lexical_cast;
using boost::numeric_cast;
......@@ -165,7 +166,7 @@ namespace AMDiS {
< boost::is_enum<T>,
void
>::type
convert(const std::string valStr, T& value)
convert(const std::string& valStr, T& value)
{
int swap = 0;
// try {
......@@ -178,7 +179,7 @@ namespace AMDiS {
/// convert special enums
inline void convert(const std::string valStr, Norm& value)
inline void convert(const std::string& valStr, Norm& value)
{
std::string swapStr = boost::to_upper_copy(valStr);
......@@ -199,7 +200,7 @@ namespace AMDiS {
/// convert value of arbitrary type to string using stringstream and
/// operator<< for type
template<typename T>
inline void convert(const T value, std::string& valStr)
inline void convert(const T& value, std::string& valStr)
{
std::stringstream ss;
ss.precision(6);
......@@ -222,20 +223,20 @@ namespace AMDiS {
// forward declarations
template< typename T >
inline void convert(const std::string valStr, WorldVector<T>& c);
inline void convert(const std::string& valStr, WorldVector<T>& c);
template<typename T>
inline void convert(const std::string valStr, std::list<T>& value);
inline void convert(const std::string& valStr, std::list<T>& value);
template<typename T>
inline void convert(const std::string valStr, std::vector<T>& value);
inline void convert(const std::string& valStr, std::vector<T>& value);
/** parse an container from tag tag. The Container must have the properties:
* - type value_type
* - member function push_back
*/
template< typename Container >
inline void getContainer(const std::string val_, Container& c)
inline void getContainer(const std::string& val_, Container& c)
{
// accepted brackets and delimiters for vector input
std::string begBrackets= "{[(";
......@@ -285,7 +286,7 @@ namespace AMDiS {
/// convert string to WorldVector
template< typename T >
inline void convert(const std::string valStr, WorldVector<T>& c)
inline void convert(const std::string& valStr, WorldVector<T>& c)
{
std::vector<T> temp_vec;
getContainer(valStr, temp_vec);
......@@ -298,7 +299,7 @@ namespace AMDiS {
/// convert string to std::list using begBrackets, endBrackets and delims
template<typename T>
inline void convert(const std::string valStr, std::list<T>& value)
inline void convert(const std::string& valStr, std::list<T>& value)
{
getContainer(valStr, value);
}
......@@ -306,7 +307,7 @@ namespace AMDiS {
/// convert string to std::vector using begBrackets, endBrackets and delims
template<typename T>
inline void convert(const std::string valStr, std::vector<T>& value)
inline void convert(const std::string& valStr, std::vector<T>& value)
{
getContainer(valStr, value);
}
......@@ -422,18 +423,19 @@ namespace AMDiS {
template<typename T>
static void get(const std::string tag, T& value, int debugInfo = -1)
{
initIntern();
// boost::shared_lock<boost::shared_mutex> lock(singlett().mutex_);
if (debugInfo == -1)
debugInfo = singlett->getMsgInfo();
debugInfo = singlett().getMsgInfo();
else {
int swap(debugInfo);
debugInfo = singlett->getMsgInfo();
singlett->msgInfo=swap;
debugInfo = singlett().getMsgInfo();
singlett().msgInfo=swap;
}
std::string valStr;
try {
int error_code = singlett->checkedGet(tag, valStr);
int error_code = singlett().checkedGet(tag, valStr);
if (error_code == 0) {
valStr = trim(valStr);
detail::convert(valStr, value);
......@@ -454,7 +456,7 @@ namespace AMDiS {
std::cout << "Parameter '" << tag << "'"
<< " initialized with: " << value << std::endl;
}
singlett->msgInfo = debugInfo;
singlett().msgInfo = debugInfo;
}
......@@ -471,8 +473,7 @@ namespace AMDiS {
std::map<std::string,std::string> &pm,
int debugInfo = -1)
{
initIntern();
for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++){
for (Initf