Commits (20)
cmake_minimum_required(VERSION 3.5.1)
# Usage of the M++ CMakeLists
#---------------------------------------------------------------------------------------#
# It is absolutely necessary to define a project name in your own project
# using the CMake command project(..) since otherwise the project path will
# not be defined correctly.
#
# Moreover, in your project the CMakeLists of M++ have to be included
# using the CMake command
# include(mpp/CMakeLists.txt)
#
# There are several options for the build process of M++. To set an option you
# can either use the CMake command
# set(<OPT_NAME> <value> CACHE STRING "<OPT_NAME>")
# in your project before including the CMakeList of M++ or you can add an optional
# flag to the CMake command, i.e.,
# cmake .. -D<OPT_NAME>=<value>
#
# In the following the options for building M++ are listed
# 1. Compiler options:
# - CXX_VERSION=17
# - COMPILER_VERSION=c++; [gnu++]
# - COMPILER_OPTIMIZE=-O3; [-O0/-O1/-O2/-Ofast]
# - NO_DEPRECATED=ON; [OFF]
# 2. Dimension options:
# - SPACE_DIM=3; [1/2]
# - TIME_DIM=1; [0]
# 3. Transformation options:
# - AFFINE_LINEAR_TRAFO=OFF; [ON]
# 4. Constant options:
# -CONST_GEOMETRIC_TOLERANCE=1e-10
# -CONST_NEAR_ZERO=1e-15
# -CONST_VERY_LARGE=1e30
# -CONST_INFTY=1e100
# 5. Interval arithmetic options:
# -USE_CXSC=OFF; [ON]
# -BUILD_CXSC_TOOLBOX=OFF; [ON]
# -BUILD_CXSC_EXAMPLES=OFF; [ON]
# -BUILD_IA_VERIFY_QUAD=OFF; [ON]
# 6. Space time options:
# -USE_SPACETIME=OFF; [ON]
# 7. Test options:
# -BUILD_TESTS=ON; [OFF]
# -BUILD_IA_TESTS=OFF; [ON]
#---------------------------------------------------------------------------------------#
# If no project directory is set yet assume that M++ is the project itself
if (NOT PROJECT_SOURCE_DIR)
cmake_minimum_required(VERSION 3.5.1)
project(M++)
set(PROJECT_MPP_DIR ${PROJECT_SOURCE_DIR})
else ()
set(PROJECT_MPP_DIR ${PROJECT_SOURCE_DIR}/mpp)
endif ()
#---------------------------------------------------------------------------------------#
message(STATUS "Project directory= " ${PROJECT_SOURCE_DIR})
message(STATUS "Mpp directory= " ${PROJECT_MPP_DIR})
execute_process(COMMAND bash -c ${PROJECT_MPP_DIR}/doc/addCommitMsgHook.sh)
# Google test
add_subdirectory(${PROJECT_MPP_DIR}/googletest)
include_directories(${PROJECT_MPP_DIR}/googletest/googletest/include)
include_directories(${PROJECT_MPP_DIR}/googletest/googlemock/include)
set(GTEST_LIB gtest gtest_main gmock gmock_main)
#---------------------------------------------------------------------------------------#
# Interval arithmetic options
set(USE_CXSC OFF CACHE STRING "USE_CXSC")
set(BUILD_CXSC_TOOLBOX OFF CACHE STRING "BUILD_CXSC_TOOLBOX")
set(BUILD_CXSC_EXAMPLES OFF CACHE STRING "BUILD_CXSC_EXAMPLES")
set(BUILD_IA_VERIFY_QUAD OFF CACHE STRING "BUILD_IA_VERIFY_QUAD")
if (BUILD_IA_TESTS OR BUILD_CXSC_TOOLBOX OR BUILD_CXSC_EXAMPLES OR BUILD_IA_VERIFY_QUAD)
set(USE_CXSC ON)
endif ()
if (BUILD_IA_VERIFY_QUAD OR BUILD_CXSC_EXAMPLES)
set(BUILD_CXSC_TOOLBOX ON)
endif ()
if (USE_CXSC)
message(STATUS "Using cxsc library for interval arithmetic computation")
add_definitions(-DBUILD_IA)
add_subdirectory(${PROJECT_MPP_DIR}/cxsc)
include_directories(${PROJECT_MPP_DIR}/cxsc/src
${PROJECT_MPP_DIR}/cxsc/src/fi_lib
${PROJECT_MPP_DIR}/cxsc/src/rts
${PROJECT_MPP_DIR}/cxsc/src/asm)
include_directories(${PROJECT_MPP_DIR}/src/intervalarithmetic)
endif ()
if (BUILD_CXSC_TOOLBOX)
message(STATUS "Building cxsc toolbox")
add_subdirectory(${PROJECT_MPP_DIR}/cxsc/CToolbox/Modules)
include_directories(${PROJECT_MPP_DIR}/cxsc/CToolbox/Modules)
endif ()
if (BUILD_CXSC_EXAMPLES)
add_subdirectory(${PROJECT_MPP_DIR}/cxsc/examples)
endif ()
if (BUILD_IA_VERIFY_QUAD)
add_subdirectory(${PROJECT_MPP_DIR}/src/intervalarithmetic/verifyquadrature)
endif ()
#---------------------------------------------------------------------------------------#
# Spacetime options
set(USE_SPACETIME OFF CACHE STRING "USE_SPACETIME")
message(STATUS "Building space time library=" ${USE_SPACETIME})
#---------------------------------------------------------------------------------------#
# MPI
find_package(MPI REQUIRED)
include_directories(${MPI_INCLUDE_PATH})
#---------------------------------------------------------------------------------------#
# Blas Lapack
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
add_definitions(-DLAPACK)
add_definitions(-DRIB)
add_definitions(-DGCC_4_4)
#---------------------------------------------------------------------------------------#
# Link superlu
message(STATUS "Using SuperLU 4.0")
add_definitions(-DSUPERLU)
add_definitions(-DLIB_PS_SUPERLU)
include_directories(${PROJECT_MPP_DIR}/superlu/include)
link_directories(${PROJECT_MPP_DIR}/superlu/lib)
if (UNIX AND NOT APPLE)
set(SUPERLU superlu_4.3)
elseif (APPLE)
set(SUPERLU superlu_4.3_mac10.10)
elseif (WIN32)
set(SUPERLU superlu_4.3_cygwin)
endif ()
#---------------------------------------------------------------------------------------#
# Compiler options
#set(CXX_VERSION "17")
#set(COMPILER_VERSION "c++")
#set(COMPILER_VERSION "gnu++")
#set(COMPILER_OPTIMIZE "-O0")
#set(COMPILER_OPTIMIZE "-O1")
#set(COMPILER_OPTIMIZE "-O2")
#set(COMPILER_OPTIMIZE "-O3")
#set(COMPILER_OPTIMIZE "-Ofast")
option(NO_DEPRECATED "Suppress deprecated warnings" OFF)
set(CMAKE_C_COMPILER ${MPI_C_COMPILER})
set(CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER})
set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS})
set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS})
set(CMAKE_CXX_FLAGS "-fPIC -g")
set(CXX_VERSION 17 CACHE STRING "CXX_VERSION")
message(STATUS "C++ version= " ${CXX_VERSION})
set(COMPILER_VERSION c++ CACHE STRING "COMPILER_VERSION")
message(STATUS "Compiler version= " ${COMPILER_VERSION})
add_compile_options(-std=${COMPILER_VERSION}${CXX_VERSION})
set(CMAKE_BUILD_TYPE distribution)
set(COMPILER_OPTIMIZE -O3 CACHE STRING "COMPILER_OPTIMIZE")
message(STATUS "Compiler optimization= " ${COMPILER_OPTIMIZE})
set(CMAKE_CXX_FLAGS_DISTRIBUTION ${COMPILER_OPTIMIZE})
set(NO_DEPRECATED ON CACHE STRING "NO_DEPRECATED")
message(STATUS "Suppress deprecated warnings= " ${NO_DEPRECATED})
if (NO_DEPRECATED)
add_compile_options(-Wno-deprecated)
endif ()
#---------------------------------------------------------------------------------------#
# Problem options
option(PROBLEM_NO_TIME "Time independent problem" OFF)
option(PROBLEM_1D "1 dimensional problem" OFF)
option(PROBLEM_2D "2 dimensional problem" OFF)
# Dimensions
set(SPACE_DIM 3 CACHE STRING "SPACE_DIM")
if (NOT SPACE_DIM MATCHES "^[1-3]$")
message(FATAL_ERROR "Space dimension must be a number from 1 to 3")
endif ()
message(STATUS "Space dimension= " ${SPACE_DIM})
add_definitions(-DSpaceDimension=${SPACE_DIM})
if (SPACE_DIM MATCHES "1")
message(FATAL_ERROR "Space dimension 1 not implemented!")
elseif (SPACE_DIM MATCHES "2")
add_definitions(-DPROBLEM_2D)
else ()
add_definitions(-DPROBLEM_3D)
endif ()
option(AFFINE_LINEAR_TRAFO "Only affine linear transformations" OFF)
set(TIME_DIM 1 CACHE STRING "TIME_DIM")
if (NOT TIME_DIM MATCHES "^[0-1]$")
message(FATAL_ERROR "Time dimension must be a number from 0 to 1")
endif ()
message(STATUS "Time dimension= " ${TIME_DIM})
add_definitions(-DTimeDimension=${TIME_DIM})
if (TIME_DIM MATCHES "1")
add_definitions(-DPROBLEM_TIMEDEP)
endif ()
#---------------------------------------------------------------------------------------#
# Constants
#set(CONST_GEOMETRIC_TOLERANCE "1e-10")
#set(CONST_NEAR_ZERO "1e-15")
#set(CONST_VERY_LARGE "1e30")
#set(CONST_INFTY "1e100")
# Transformation
set(AFFINE_LINEAR_TRAFO OFF CACHE STRING "AFFINE_LINEAR_TRAFO")
message(STATUS "Affine linear transformations= " ${AFFINE_LINEAR_TRAFO})
if (AFFINE_LINEAR_TRAFO)
add_definitions(-DAFFINE_TRANSFORMATION=1)
else ()
add_definitions(-DAFFINE_TRANSFORMATION=0)
endif ()
#---------------------------------------------------------------------------------------#
# SuperLU options
option(USE_SUPERLU30 "Use SuperLU 3.0 (old version)" OFF)
# Constants
set(CONST_GEOMETRIC_TOLERANCE 1e-10 CACHE STRING "CONST_GEOMETRIC_TOLERANCE")
message(STATUS "Geometric tolerance= " ${CONST_GEOMETRIC_TOLERANCE})
add_definitions(-DGeometricTolerance=${CONST_GEOMETRIC_TOLERANCE})
set(CONST_NEAR_ZERO 1e-15 CACHE STRING "CONST_NEAR_ZERO")
message(STATUS "Near zero= " ${CONST_NEAR_ZERO})
add_definitions(-DnearToZero=${CONST_NEAR_ZERO})
set(CONST_VERY_LARGE 1e30 CACHE STRING "CONST_VERY_LARGE")
message(STATUS "Very large= " ${CONST_VERY_LARGE})
add_definitions(-DVeryLarge=${CONST_VERY_LARGE})
set(CONST_INFTY 1e100 CACHE STRING "CONST_INFTY")
message(STATUS "Infinity= " ${CONST_INFTY})
add_definitions(-Dinfty=${CONST_INFTY})
#---------------------------------------------------------------------------------------#
# Interval arithmetic options
option(USE_CXSC "Use interval arithmetic library cxsc" OFF)
option(BUILD_CXSC_TOOLBOX "Build cxsc toolbox" OFF)
option(BUILD_CXSC_EXAMPLES "Build cxsc example executables" OFF)
# Manage folder structure build folder
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/vtk)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/gp)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/py)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/vtu)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/log)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/dual)
#---------------------------------------------------------------------------------------#
# Spacetime options
option(USE_SPACETIME "Use spacetime core library" OFF)
# Include directories
include_directories(${PROJECT_MPP_DIR}/src/lib0_basic/utility)
include_directories(${PROJECT_MPP_DIR}/src/lib0_basic/parallel)
include_directories(${PROJECT_MPP_DIR}/src/lib0_basic)
include_directories(${PROJECT_MPP_DIR}/src/lib0_basic/intervalarithmetic)
include_directories(${PROJECT_MPP_DIR}/src/lib1_math/basicalgebra)
include_directories(${PROJECT_MPP_DIR}/src/lib1_math)
include_directories(${PROJECT_MPP_DIR}/src/lib2_mesh/meshparts)
include_directories(${PROJECT_MPP_DIR}/src/lib2_mesh/cells)
include_directories(${PROJECT_MPP_DIR}/src/lib2_mesh/mesh)
include_directories(${PROJECT_MPP_DIR}/src/lib2_mesh/mesh/datamesh)
include_directories(${PROJECT_MPP_DIR}/src/lib2_mesh)
include_directories(${PROJECT_MPP_DIR}/src/lib3_disc/dof)
include_directories(${PROJECT_MPP_DIR}/src/lib3_disc/discretization)
include_directories(${PROJECT_MPP_DIR}/src/lib3_disc/quadrature)
include_directories(${PROJECT_MPP_DIR}/src/lib3_disc/shapes)
include_directories(${PROJECT_MPP_DIR}/src/lib3_disc)
include_directories(${PROJECT_MPP_DIR}/src/lib4_vector/matrixgraph)
include_directories(${PROJECT_MPP_DIR}/src/lib4_vector/plot)
include_directories(${PROJECT_MPP_DIR}/src/lib4_vector/algebra)
include_directories(${PROJECT_MPP_DIR}/src/lib4_vector/spectrum)
include_directories(${PROJECT_MPP_DIR}/src/lib4_vector)
include_directories(${PROJECT_MPP_DIR}/src/lib5_elem)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/solver)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/solver/linearsolver)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/solver/preconditioner)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/timeseries)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/timestepping)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers/eigensolver)
include_directories(${PROJECT_MPP_DIR}/src/lib6_solvers)
include_directories(${PROJECT_MPP_DIR}/LIB_PS)
include_directories(${PROJECT_MPP_DIR}/src)
#---------------------------------------------------------------------------------------#
# Test options
option(BUILD_TESTS "Build test executables" ON)
option(BUILD_IA_TESTS "Build interval arithmetic test executables" OFF)
option(BUILD_IA_VERIFY_QUAD "Build interval arithmetic quadrature verification executables" OFF)
# Subdirectories
add_subdirectory(${PROJECT_MPP_DIR}/LIB_PS)
add_subdirectory(${PROJECT_MPP_DIR}/src)
#---------------------------------------------------------------------------------------#
# Set path for mpp
set(PROJECT_MPP_DIR ${PROJECT_SOURCE_DIR})
# Test macro to add mpp tests
macro(add_mpp_test testpath)
# To remove pathnames infront of testname
string(FIND ${testpath} "/" pos REVERSE)
MATH(EXPR pos "${pos}+1")
string(SUBSTRING ${testpath} ${pos} -1 testname)
add_executable(${testname} ${testpath}.cpp)
target_link_libraries(${testname} ${MPP_TEST_LIBRARIES})
add_test(${testname} ${testname})
endmacro()
# Tests
set(BUILD_TESTS ON CACHE STRING "BUILD_TESTS")
message(STATUS "Building mpp unit tests= " ${BUILD_TESTS})
set(BUILD_IA_TESTS OFF CACHE STRING "BUILD_IA_TESTS")
message(STATUS "Building mpp interval arithmetic unit tests= " ${BUILD_IA_TESTS})
include_directories(${PROJECT_MPP_DIR}/tests/_testenvironment)
add_subdirectory(${PROJECT_MPP_DIR}/tests/_testenvironment)
# Include settings for mpp
include(CMakeListsMpp.inc)
set(MPP_TEST_LIBRARIES MPP_LIBRARIES MPP_TESTENV ${GTEST_LIB})
include_directories(${PROJECT_MPP_DIR}/tests/)
include_directories(${PROJECT_MPP_DIR}/tests/intervalarithmetic)
enable_testing()
if (BUILD_TESTS)
add_subdirectory(${PROJECT_MPP_DIR}/tests/)
endif ()
if (BUILD_IA_TESTS)
add_subdirectory(${PROJECT_MPP_DIR}/tests/intervalarithmetic)
endif ()
#---------------------------------------------------------------------------------------#
# Includes for the mpp library
#---------------------------------------------------------------------------------------#
execute_process(COMMAND bash -c ${PROJECT_MPP_DIR}/doc/addCommitMsgHook.sh)
# Google test
add_subdirectory(${PROJECT_MPP_DIR}/googletest)
include_directories(${PROJECT_MPP_DIR}/googletest/googletest/include)
include_directories(${PROJECT_MPP_DIR}/googletest/googlemock/include)
set(GTEST_LIB gtest gtest_main gmock gmock_main)
#---------------------------------------------------------------------------------------#
# Build cxsc interval arithmetic library
if (USE_CXSC)
message(STATUS "Using cxsc library for interval arithmetic computation")
add_definitions(-DBUILD_IA)
add_subdirectory(${PROJECT_MPP_DIR}/cxsc)
include_directories(${PROJECT_MPP_DIR}/cxsc/src
${PROJECT_MPP_DIR}/cxsc/src/fi_lib
${PROJECT_MPP_DIR}/cxsc/src/rts
${PROJECT_MPP_DIR}/cxsc/src/asm)
include_directories(${PROJECT_MPP_DIR}/src/intervalarithmetic)
else ()
set(BUILD_CXSC_TOOLBOX OFF)
set(BUILD_CXSC_EXAMPLES OFF)
set(BUILD_IA_TESTS OFF)
set(BUILD_IA_VERIFY_QUAD OFF)
endif ()
if (BUILD_IA_VERIFY_QUAD OR BUILD_CXSC_EXAMPLES)
set(BUILD_CXSC_TOOLBOX ON)
endif ()
#---------------------------------------------------------------------------------------#
# MPI
find_package(MPI REQUIRED)
include_directories(${MPI_INCLUDE_PATH})
set(CMAKE_C_COMPILER ${MPI_C_COMPILER})
set(CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER})
set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS})
set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS})
set(CMAKE_CXX_FLAGS "-fPIC -g")
if (NOT CXX_VERSION)
set(CXX_VERSION "17")
endif ()
message(STATUS "C++ version= " ${CXX_VERSION})
if (NOT COMPILER_VERSION)
set(COMPILER_VERSION "c++")
endif()
message(STATUS "Compiler version= " ${COMPILER_VERSION})
add_compile_options(-std=${COMPILER_VERSION}${CXX_VERSION})
set(CMAKE_BUILD_TYPE distribution)
if (NOT COMPILER_OPTIMIZE)
set(COMPILER_OPTIMIZE "-Ofast")
endif ()
message(STATUS "Compiler optimization= " ${COMPILER_OPTIMIZE})
set(CMAKE_CXX_FLAGS_DISTRIBUTION ${COMPILER_OPTIMIZE})
if (NO_DEPRECATED)
add_compile_options(-Wno-deprecated)
endif ()
#---------------------------------------------------------------------------------------#
# Blas Lapack
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
add_definitions(-DLAPACK)
add_definitions(-DRIB)
add_definitions(-DGCC_4_4)
#---------------------------------------------------------------------------------------#
# Manage folder structure build folder
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/vtk)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/gp)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/py)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/vtu)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/log)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/data/dual)
#---------------------------------------------------------------------------------------#
# Link superlu
if (USE_SUPERLU30)
message(FATAL_ERROR "SuperLU 3.0 not available!")
add_definitions(-DSUPERLU30)
add_definitions(-DLIB_PS_SUPERLU30)
include_directories(${PROJECT_MPP_DIR}/superlu/include)
link_directories(${PROJECT_MPP_DIR}/superlu/lib)
else ()
message(STATUS "Using SuperLU 4.0")
add_definitions(-DSUPERLU)
add_definitions(-DLIB_PS_SUPERLU)
include_directories(${PROJECT_MPP_DIR}/superlu/include)
link_directories(${PROJECT_MPP_DIR}/superlu/lib)
if (UNIX AND NOT APPLE)
set(SUPERLU superlu_4.3)
elseif (APPLE)
set(SUPERLU superlu_4.3_mac10.10)
elseif (WIN32)
set(SUPERLU superlu_4.3_cygwin)
endif ()
endif ()
#---------------------------------------------------------------------------------------#
# Problem options
if (PROBLEM_NO_TIME)
message(STATUS "Time independent problem")
add_definitions(-DTimeDimension=0)
else ()
message(STATUS "Time dependent problem")
add_definitions(-DTimeDimension=1)
add_definitions(-DPROBLEM_TIMEDEP)
endif ()
if (PROBLEM_1D)
message(FATAL_ERROR "Space dimension 1 not implemented!")
elseif (PROBLEM_2D)
message(STATUS "2 dimensional problem")
add_definitions(-DPROBLEM_2D)
add_definitions(-DSpaceDimension=2)
else ()
message(STATUS "3 dimensional problem")
add_definitions(-DPROBLEM_3D)
add_definitions(-DSpaceDimension=3)
endif ()
if (AFFINE_LINEAR_TRAFO)
message(STATUS "Only affine linear transformations")
add_definitions(-DAFFINE_TRANSFORMATION=1)
else ()
message(STATUS "General transformations")
add_definitions(-DAFFINE_TRANSFORMATION=0)
endif ()
#---------------------------------------------------------------------------------------#
# Constants
if (NOT CONST_GEOMETRIC_TOLERANCE)
set(CONST_GEOMETRIC_TOLERANCE "1e-10")
endif ()
message(STATUS "Geometric tolerance= " ${CONST_GEOMETRIC_TOLERANCE})
if (NOT CONST_NEAR_ZERO)
set(CONST_NEAR_ZERO "1e-15")
endif ()
message(STATUS "is near zero= " ${CONST_NEAR_ZERO})
if (NOT CONST_VERY_LARGE)
set(CONST_VERY_LARGE "1e30")
endif ()
message(STATUS "very large= " ${CONST_VERY_LARGE})
if (NOT CONST_INFTY)
set(CONST_INFTY "1e100")
endif ()
message(STATUS "infinity= " ${CONST_INFTY})
set(CONST_COMPILER_FLAGS
-DGeometricTolerance=${CONST_GEOMETRIC_TOLERANCE}
-DnearToZero=${CONST_NEAR_ZERO}
-DVeryLarge=${CONST_VERY_LARGE}
-Dinfty=${CONST_INFTY})
add_definitions(${CONST_COMPILER_FLAGS})
#---------------------------------------------------------------------------------------#
# Include directories
include_directories(${PROJECT_MPP_DIR}/LIB_PS)
include_directories(${PROJECT_MPP_DIR}/src)
#---------------------------------------------------------------------------------------#
# Subdirectories
add_subdirectory(${PROJECT_MPP_DIR}/LIB_PS)
add_subdirectory(${PROJECT_MPP_DIR}/src)
#---------------------------------------------------------------------------------------#
# Mpp libraries
set(MPP_LIBRARIES
SRC
LIB_PS
${SUPERLU}
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES})
if (USE_CXSC)
set(MPP_LIBRARIES ${MPP_LIBRARIES} cxsc)
endif ()
#---------------------------------------------------------------------------------------#
# Tests
include_directories(${PROJECT_MPP_DIR}/tests/_testenvironment)
add_subdirectory(${PROJECT_MPP_DIR}/tests/_testenvironment)
set(MPP_TEST_LIBRARIES ${MPP_LIBRARIES} MPP_TESTENV ${GTEST_LIB})
include_directories(${PROJECT_MPP_DIR}/tests/)
include_directories(${PROJECT_MPP_DIR}/tests/intervalarithmetic)
enable_testing()
macro(add_mpp_test testpath)
# To remove pathnames infront of testname
string(FIND ${testpath} "/" pos REVERSE)
MATH(EXPR pos "${pos}+1")
string(SUBSTRING ${testpath} ${pos} -1 testname)
add_executable(${testname} ${testpath}.cpp)
target_link_libraries(${testname} ${MPP_TEST_LIBRARIES})
add_test(${testname} ${testname})
endmacro()
if (BUILD_TESTS)
message(STATUS "Building mpp unit tests")
add_subdirectory(${PROJECT_MPP_DIR}/tests/)
endif ()
if (BUILD_IA_TESTS)
message(STATUS "Building mpp interval arithmetic unit tests")
add_subdirectory(${PROJECT_MPP_DIR}/tests/intervalarithmetic)
endif ()
#---------------------------------------------------------------------------------------#
if (BUILD_CXSC_TOOLBOX)
message(STATUS "Building cxsc toolbox")
add_subdirectory(${PROJECT_MPP_DIR}/cxsc/CToolbox/Modules)
include_directories(${PROJECT_MPP_DIR}/cxsc/CToolbox/Modules)
endif ()
if (BUILD_CXSC_EXAMPLES)
add_subdirectory(${PROJECT_MPP_DIR}/cxsc/examples)
endif ()
if (BUILD_IA_VERIFY_QUAD)
add_subdirectory(${PROJECT_MPP_DIR}/src/intervalarithmetic/verifyquadrature)
endif ()
include_directories(${PROJECT_SOURCE_DIR}/src/shapes)
set(src
geometry/Point.cpp
QuadratureInterval.cpp
QuadratureTriangle.cpp
QuadratureTetrahedron.cpp
Quadrature.cpp
shapes/Shapes.cpp
Identify.cpp
Interpolate.cpp
Distribution.cpp
dof/DoF.cpp
Interface.cpp
Algebra.cpp
LazyVectors.cpp
Sparse.cpp
Transfer.cpp
Small.cpp
Euler.cpp
TimeSeries.cpp
m++.cpp)
include(parallel/CMakeLists.txt)
include(matrixgraph/CMakeLists.txt)
include(mesh/CMakeLists.txt)
include(elements/CMakeLists.txt)
include(cells/CMakeLists.txt)
include(plot/CMakeLists.txt)
include(spectrum/CMakeLists.txt)
include(utility/CMakeLists.txt)
include(solver/CMakeLists.txt)
include(basicalgebra/CMakeLists.txt)
include(timeseries/CMakeLists.txt)
include(timestepping/CMakeLists.txt)
set(mpp_src ${src} ${utility} ${parallel} ${cell}
${mesh} ${matrixgraph} ${discretization}
${elements} ${solver} ${plot} ${spectrum} ${basicalgebra}
${timeseries} ${timestepping})
if (USE_CXSC)
include(intervalarithmetic/CMakeLists.txt)
add_library(SRC STATIC ${mpp_src} ${intervalarithmetic})
elseif (USE_SPACETIME)
include(spacetime/CMakeLists.txt)
add_library(SRC STATIC ${mpp_src} ${spacetimelib})
else ()
add_library(SRC STATIC ${mpp_src})
endif ()
add_subdirectory(lib0_basic)
add_subdirectory(lib1_math)
add_subdirectory(lib2_mesh)
add_subdirectory(lib3_disc)
add_subdirectory(lib4_vector)
add_subdirectory(lib5_elem)
add_subdirectory(lib6_solvers)
add_library(MPP_LIBRARIES STATIC m++.cpp)
target_link_libraries(MPP_LIBRARIES LIB_SOLVERS)
#include "Dissect.hpp"
#include "Small.hpp"
#include "Sparse.hpp"
#include "Tensor.hpp"
#include <cmath>
#include <algorithm>
#include <vector>
class Dissect : public Preconditioner {
Dissect *Dissect0;
Dissect *Dissect1;
vector<int> separator;
vector<int> indices_below0;
vector<int> indices_below1;
vector<vector<SparseMatrix *>> K;
vector<vector<LapackMatrix *>> D;
vector<vector<SVDMatrix *>> S;
int nb_bissection;
public:
Dissect()
: separator(0), Dissect0(NULL), Dissect1(NULL), nb_bissection(0) {
config.get("Number_bissection", nb_bissection)
}
private:
void Construct(const Matrix &);
void bissection(const Matrix &, const Vector &,
int, vector<cell> &, vector<bool> &, char, int);
void cut_level0(const Vector &, vector<cell>, vector<int> &,
vector<bool> &, vector<bool> &);
void cut(const Vector &, vector<cell>, vector<cell> &, vector<cell> &,
vector<int> &, vector<bool> &, vector<bool> &, char, int);
void Get_Indices_Below(Dissect *, vector<int> &);
void MatrixAssembler(const Matrix &, int);
void clean();
void Destruct();
virtual ~Dissect() { Destruct(); }
void block_sep(Dissect *, LapackMatrix &, int);
void Solver(LapackMatrix &, LapackMatrix &, LapackMatrix &, int, int);
void multiply(Vector &, const Vector &) const;
void initialize(const Vector &, SmallVector &, SmallVector &, SmallVector &) const;
void function(const Vector &, SmallVector &, SmallVector &, SmallVector &, int) const;
void multiply_Small(const Vector &, SmallVector &, const SmallVector &, int) const;
void basic_solver(LapackMatrix &, SmallVector &) const;
void copy(Vector &,
const SmallVector &,
const SmallVector &,
const SmallVector &) const;
void copy(SmallVector &u,
const SmallVector &b0,
const SmallVector &b1,
const SmallVector &b2) const;
friend ostream &operator<<(ostream &s, const Dissect &K) {
return s << "NestedDissection";
}
string Name() const { return "NestedDissection"; }
};
void setSparse(int,
int,
const SparseMatrix &,
const vector<int> &,
const vector<int> &,
SparseMatrix &);
void multi(SmallVector &, const LapackMatrix &, const SmallVector &);
void function2(vector<vector<LapackMatrix *>>,
SmallVector &,
SmallVector &,
SmallVector &);
void copy(Vector &, const SmallVector &, const SmallVector &, const SmallVector &);
inline bool Less_x(const cell &c0, const cell &c1) {
const Point &P = c0();
const Point &Q = c1();
if (P[0] < Q[0] - GeometricTolerance) return true;
if (P[0] > Q[0] + GeometricTolerance) return false;
if (P[1] < Q[1] - GeometricTolerance) return true;
if (P[1] > Q[1] + GeometricTolerance) return false;
if (P[2] < Q[2] - GeometricTolerance) return true;
return false;
}
inline bool Less_y(const cell &c0, const cell &c1) {
const Point &P = c0();
const Point &Q = c1();
if (P[1] < Q[1] - GeometricTolerance) return true;
if (P[1] > Q[1] + GeometricTolerance) return false;
if (P[2] < Q[2] - GeometricTolerance) return true;
if (P[2] > Q[2] + GeometricTolerance) return false;
if (P[0] < Q[0] - GeometricTolerance) return true;
return false;
}
inline bool Less_z(const cell &c0, const cell &c1) {
const Point &P = c0();
const Point &Q = c1();
if (P[2] < Q[2] - GeometricTolerance) return true;
if (P[2] > Q[2] + GeometricTolerance) return false;
if (P[0] < Q[0] - GeometricTolerance) return true;
if (P[0] > Q[0] + GeometricTolerance) return false;
if (P[1] < Q[1] - GeometricTolerance) return true;
return false;
}
//--------------------------------------------------
//------SparseMatrix constructor with indices-------
//--------------------------------------------------
void setSparse(int n,
int m,
const SparseMatrix &S,
const vector<int> &Indices,
const vector<int> &Indices2,
SparseMatrix &M) {
int nonzero = 0;
int size = S.size();
if (Indices.size() == 0 || Indices2.size() == 0) mout << "wrong size for indices\n";
vector<int> searchindex;
searchindex.resize(size);
for (int i = 0; i < searchindex.size(); ++i) searchindex[i] = -1;
for (int i = 0; i < Indices2.size(); ++i) searchindex[Indices2[i]] = i;
for (int i = 0; i < Indices.size(); ++i)
for (int k = S.rowind(Indices[i]); k < S.rowind(Indices[i] + 1); ++k)
if (searchindex[S.colptr(k)] != -1)
nonzero++;
M.resize(n, nonzero);
int mi = 0;
M.rowind(0) = 0;
for (int i = 0; i < Indices.size(); ++i) {
M.rowind(i + 1) = M.rowind(i);
for (int k = S.rowind(Indices[i]); k < S.rowind(Indices[i] + 1); ++k) {
int akt = searchindex[S.colptr(k)];
if (akt != -1) {
M.colptr(mi) = akt;
M.nzval(mi) = S.nzval(k);
++M.rowind(i + 1);
mi++;
}
}
}
}
//----------------------------------------------------------
//------------------Lapack*smallvect------------------------
//----------------------------------------------------------
void multi(SmallVector &f, const LapackMatrix &A, const SmallVector &u) {
for (int j = 0; j < f.size(); ++j) {
Scalar s = 0;
for (int k = 0; k < u.size(); ++k)
s += A(j, k) * u[k];
f[j] = s;
}
}
//----------------------------------------------------
//-----------------Constructor------------------------
//----------------------------------------------------
void Dissect::Construct(const Matrix &A) {
Vector v(A.GetVector());
const Mesh &M = v.GetMesh();
vector<cell> C(M.Cells::size());
vector<bool> on_sep(v.size(), false);
bissection(A, v, nb_bissection, C, on_sep, 'x', M.dim());
}
void Dissect::bissection(const Matrix &A, const Vector &U, int nb,
vector<cell> &C, vector<bool> &on_sep,
char d, int dimension) {
const Mesh &M = U.GetMesh();
vector<bool> done(U.nR(), false);
int N = U.size();
separator.resize(N);
if (C.size() == (M.Cells::size())) {
int nC = 0;
for (cell c = M.cells(); c != M.cells_end(); ++c) C[nC++] = c;
sort(C.begin(), C.end(), Less_x);
}
if (nb >= 1) {
vector<cell> C0;
vector<cell> C1;
switch (d) {
case 'x':
cut(U, C, C0, C1, separator, on_sep, done, 'x', dimension);
break;
case 'y':
cut(U, C, C0, C1, separator, on_sep, done, 'y', dimension);
break;
case 'z':
cut(U, C, C0, C1, separator, on_sep, done, 'z', dimension);
}
Dissect0 = new Dissect();
Dissect1 = new Dissect();
nb--;
int nb0 = nb;
int nb1 = nb;
if (dimension == 3) {
switch (d) {
case 'x':
(*Dissect0).bissection(A, U, nb0, C0, on_sep, 'y', dimension);
(*Dissect1).bissection(A, U, nb1, C1, on_sep, 'y', dimension);
break;
case 'y':
(*Dissect0).bissection(A, U, nb0, C0, on_sep, 'z', dimension);
(*Dissect1).bissection(A, U, nb1, C1, on_sep, 'z', dimension);
break;
case 'z':
(*Dissect0).bissection(A, U, nb0, C0, on_sep, 'x', dimension);
(*Dissect1).bissection(A, U, nb1, C1, on_sep, 'x', dimension);
}
}
if (dimension == 2) {
switch (d) {
case 'x':
(*Dissect0).bissection(A, U, nb0, C0, on_sep, 'y', dimension);
(*Dissect1).bissection(A, U, nb1, C1, on_sep, 'y', dimension);
break;
case 'y':
(*Dissect0).bissection(A, U, nb0, C0, on_sep, 'x', dimension);
(*Dissect1).bissection(A, U, nb1, C1, on_sep, 'x', dimension);
}
}
Get_Indices_Below(Dissect0, indices_below0);
Get_Indices_Below(Dissect1, indices_below1);
if (indices_below0.size() == 0 || indices_below1.size() == 0) {
mout << "Nested_Dissection impossible\n";
exit(0);
} else MatrixAssembler(A, nb);
} else {
Dissect0 = NULL;
Dissect1 = NULL;
cut_level0(U, C, separator, on_sep, done);
indices_below0.resize(0);
indices_below1.resize(0);
}
}
void Dissect::cut_level0(const Vector &U,
vector<cell> C,
vector<int> &INDsep,
vector<bool> &on_sep,
vector<bool> &done) {
int nC = 0;
int j0 = 0;
for (int k = nC; k < C.size(); ++k) {
rows R(U, C[k]);
for (int j = 0; j < R.size(); ++j) {
int id = R[j].Id();
int i = U.Index(id);
int n = R[j].n();
for (int k = 0; k < n; ++k)
if (on_sep[id]) {
if (done[id] == false)
done[id] = true;
} else {
if (done[id] == false)
for (int k = 0; k < n; ++k)
INDsep[j0++] = i + k;
done[id] = true;
}
}
}
INDsep.resize(j0);
sort(INDsep.begin(), INDsep.end());
}
void Dissect::cut(const Vector &U,
vector<cell> C,
vector<cell> &C0,
vector<cell> &C1,
vector<int> &INDsep,
vector<bool> &on_sep,
vector<bool> &done,
char d,
int dimension) {
int j2 = 0;
vector<bool> mark(U.nR(), false);
int nb_C = C.size() / 2;
C0.resize(nb_C);
for (int k = 0; k < nb_C; ++k) {
C0[k] = C[k];
rows R(U, C[k]);
for (int j = 0; j < R.size(); ++j) {
int id = R[j].Id();
mark[id] = true;
}
}
int nb_C2 = C.size() - nb_C;
C1.resize(nb_C2);
for (int k = nb_C; k < C.size(); ++k) {
C1[k - nb_C] = C[k];
rows R(U, C[k]);
for (int j = 0; j < R.size(); ++j) {
int id = R[j].Id();
int i = U.Index(id);
int n = R[j].n();
for (int k = 0; k < n; ++k)
if (mark[id]) {
if (done[id] == false && on_sep[id] == false) {
for (int k = 0; k < n; ++k) {
INDsep[j2++] = i + k;
on_sep[i + k] = true;
}
done[id] = true;
}
}
}
}
INDsep.resize(j2);
sort(INDsep.begin(), INDsep.end());
if (dimension == 3) {
switch (d) {
case 'x':
sort(C0.begin(), C0.end(), Less_y);
sort(C1.begin(), C1.end(), Less_y);
break;
case 'y':
sort(C0.begin(), C0.end(), Less_z);
sort(C1.begin(), C1.end(), Less_z);
break;
case 'z':
sort(C0.begin(), C0.end(), Less_x);
sort(C1.begin(), C1.end(), Less_x);
}
}
if (dimension == 2) {
switch (d) {
case 'x':
sort(C0.begin(), C0.end(), Less_y);
sort(C1.begin(), C1.end(), Less_y);
break;
case 'y':
sort(C0.begin(), C0.end(), Less_x);
sort(C1.begin(), C1.end(), Less_x);
}
}
}
void Dissect::Get_Indices_Below(Dissect *Dis, vector<int> &indices_below) {
int n0 = ((*Dis).indices_below0).size();
int m0 = ((*Dis).indices_below1).size();
int p0 = ((*Dis).separator).size();
indices_below.resize(n0 + m0 + p0);
for (int i = 0; i < n0; i++)
indices_below[i] = ((*Dis).indices_below0)[i];
for (int i = 0; i < m0; i++)
indices_below[i + n0] = ((*Dis).indices_below1)[i];
for (int i = 0; i < p0; i++)
indices_below[i + n0 + m0] = ((*Dis).separator)[i];
}
void Dissect::MatrixAssembler(const Matrix &A, int nb_d) {
SparseMatrix T(A);
K.resize(3);
D.resize(3);
for (int i = 0; i < 3; ++i) {
K[i].resize(3);
D[i].resize(3);