diff --git a/cmake/AkantuBuildTreeSettings.cmake.in b/cmake/AkantuBuildTreeSettings.cmake.in index 0fddeb0ab..10bda8f9b 100644 --- a/cmake/AkantuBuildTreeSettings.cmake.in +++ b/cmake/AkantuBuildTreeSettings.cmake.in @@ -1,37 +1,37 @@ #=============================================================================== # @file AkantuBuildTreeSettings.cmake.in # # @author Nicolas Richart # # @date creation: Thu Dec 01 2011 # @date last modification: Sun Oct 19 2014 # # @brief Configuration for link with build tree # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== -set(AKANTU_INCLUDE_DIR +set(AKANTU_INCLUDE_DIRS "@AKANTU_INCLUDE_DIRS@" ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake/Modules") \ No newline at end of file +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake/Modules") diff --git a/cmake/AkantuConfig.cmake.in b/cmake/AkantuConfig.cmake.in index b53e58447..a1c8a82db 100644 --- a/cmake/AkantuConfig.cmake.in +++ b/cmake/AkantuConfig.cmake.in @@ -1,68 +1,68 @@ #=============================================================================== # @file AkantuConfig.cmake.in # # @author Nicolas Richart # # @date creation: Thu Dec 01 2011 # @date last modification: Mon Jan 18 2016 # # @brief CMake file for the library # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== # Compute paths get_filename_component(AKANTU_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(AKANTU_USE_FILE "${AKANTU_CMAKE_DIR}/AkantuUse.cmake") include(${AKANTU_USE_FILE}) if(EXISTS "${AKANTU_CMAKE_DIR}/CMakeCache.txt") # In build tree include("${AKANTU_CMAKE_DIR}/AkantuBuildTreeSettings.cmake") include(AkantuSimulationMacros) else() # In install tree - set(AKANTU_INCLUDE_DIR "${AKANTU_CMAKE_DIR}/../../include/akantu") - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${AKANTU_CMAKE_DIR}/cmake") + set(AKANTU_INCLUDE_DIRS "${AKANTU_CMAKE_DIR}/../../include/akantu") + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${AKANTU_CMAKE_DIR}") include(AkantuSimulationMacros) endif() include("${AKANTU_CMAKE_DIR}/AkantuLibraryDepends.cmake") # Dependencies include("${AKANTU_CMAKE_DIR}/AkantuConfigInclude.cmake") set(AKANTU_BUILD_TYPE @CMAKE_BUILD_TYPE@) # find_akantu_dependencies() set(AKANTU_LIBRARY akantu) if(AKANTU_HAS_CORE_CXX11) - add_definitions(-std=c++0x) + add_definitions(${AKANTU_CORE_CXX11_COMPILE_CXX_FLAGS}) endif() list(APPEND AKANTU_LIBRARIES ${AKANTU_LIBRARY} ${AKANTU_EXTRA_LIBRARIES}) -list(APPEND AKANTU_INCLUDE_DIR ${AKANTU_EXTRA_INCLUDE_DIR}) +list(APPEND AKANTU_INCLUDE_DIRS ${AKANTU_EXTRA_INCLUDE_DIR}) # set(AKANTU_VERSION @AKANTU_VERSION@) # @PACKAGE_INIT@ # set_and_check(AKANTU_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") # check_required_components(Akantu) diff --git a/cmake/AkantuSimulationMacros.cmake b/cmake/AkantuSimulationMacros.cmake index c072a53e3..a7384f3cf 100644 --- a/cmake/AkantuSimulationMacros.cmake +++ b/cmake/AkantuSimulationMacros.cmake @@ -1,168 +1,171 @@ #=============================================================================== # @file AkantuSimulationMacros.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Jan 18 2016 # @date last modification: Wed Jan 20 2016 # # @brief macros for examples # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # # @section DESCRIPTION # #=============================================================================== if(__AKANTU_SIMULATION_MACROS) return() endif() set(__AKANTU_SIMULATION_MACROS TRUE) #=============================================================================== function(add_akantu_simulation simulation_name) _add_akantu_simulation(${simulation_name} ${ARGN}) endfunction() #=============================================================================== function(_add_akantu_simulation simulation_name) set(multi_variables SCRIPT SOURCES FILES_TO_COPY DEPENDS DIRECTORIES_TO_CREATE COMPILE_OPTIONS USE_PACKAGES ) cmake_parse_arguments(_simulation "" "LIST_FILES" "${multi_variables}" ${ARGN} ) set(_deps_OK TRUE) if(_simulation_USE_PACKAGES) foreach(_pkg ${_simulation_USE_PACKAGES}) package_is_activated(${_pkg} _activated) if(_activated) package_get_include_dir(${_pkg} _inc_dir) list(APPEND _simulation_INCLUDE_DIRS ${_inc_dir}) package_get_libraries(${_pkg} _libraries) list(APPEND _simulation_LIBRARIES ${_libraries}) package_get_compile_flags(${_pkg} CXX _flags) list(APPEND _simulation_COMPILE_FLAGS "${_flags}") else() message("${simulation_name} use ${_pkg} but Akantu " " has been compiled without this package") set(_deps_OK FALSE) endif() endforeach() endif() package_is_activated(CORE_CXX11 _activated) if(_activated) package_get_compile_flags(CORE_CXX11 CXX _flags) list(APPEND _simulation_COMPILE_FLAGS "${_flags}") endif() package_get_compile_flags(BOOST CXX _flags) list(APPEND _simulation_COMPILE_FLAGS "${_flags}") + package_get_include_dir(BOOST _inc_dir) + list(APPEND _simulation_INCLUDE_DIRS ${_inc_dir}) + string(REPLACE ";" " " _tmp_flags "${_simulation_COMPILE_FLAGS}") string(REGEX REPLACE " +" " " _simulation_COMPILE_FLAGS "${_tmp_flags}") if(_deps_OK) if(_simulation_UNPARSED_ARGUMENTS OR _simulation_SOURCES) add_executable(${simulation_name} ${_simulation_UNPARSED_ARGUMENTS} ${_simulation_SOURCES}) target_link_libraries(${simulation_name} akantu ${_simulation_LIBRARIES}) target_include_directories(${simulation_name} PRIVATE ${AKANTU_INCLUDE_DIRS} ${_simulation_INCLUDE_DIRS}) if(_simulation_DEPENDS) foreach(_deps ${_simulation_DEPENDS}) get_target_property(_type ${_deps} TYPE) if(_type STREQUAL "SHARED_LIBRARY" OR _type STREQUAL "STATIC_LIBRARY") target_link_libraries(${simulation_name} ${_deps}) else() add_dependencies(${simulation_name} ${_deps}) endif() endforeach() endif() if(_simulation_COMPILE_OPTIONS) set_target_properties(${simulation_name} PROPERTIES COMPILE_DEFINITIONS "${_simulation_COMPILE_OPTIONS}") endif() if(_simulation_COMPILE_FLAGS) set_target_properties(${simulation_name} PROPERTIES COMPILE_FLAGS "${_simulation_COMPILE_FLAGS}") endif() endif() if(_simulation_SCRIPT) file(COPY ${_simulation_SCRIPT} DESTINATION .) endif() # copy the needed files to the build folder if(_simulation_FILES_TO_COPY) file(COPY ${_simulation_FILES_TO_COPY} DESTINATION .) endif() # create the needed folders in the build folder if(_simulation_DIRECTORIES_TO_CREATE) foreach(_dir ${_simulation_DIRECTORIES_TO_CREATE}) if(IS_ABSOLUTE ${dir}) file(MAKE_DIRECTORY ${_dir}) else() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir}) endif() endforeach() endif() endif() if(_simulation_LIST_FILES) set(_simulation_files) foreach(_file ${_simulation_SCRIPT} ${_simulation_SOURCES} ${_simulation_UNPARSED_ARGUMENTS} ${_simulation_FILES_TO_COPY}) list(APPEND _simulation_files ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) endforeach() foreach(_dep ${_simulation_DEPENDS}) get_target_list_of_associated_files(${_dep} _dep_ressources) if(_dep_ressources) list(APPEND _simulation_files "${_dep_ressources}") endif() endforeach() set(${_simulation_LIST_FILES} ${_simulation_files} PARENT_SCOPE) endif() endfunction() diff --git a/cmake/AkantuUse.cmake b/cmake/AkantuUse.cmake index c7f17e61c..863d17d2d 100644 --- a/cmake/AkantuUse.cmake +++ b/cmake/AkantuUse.cmake @@ -1,69 +1,69 @@ #=============================================================================== # @file AkantuUse.cmake # # @author Nicolas Richart # # @date creation: Tue Dec 07 2010 # @date last modification: Mon Aug 17 2015 # # @brief CMake file for the library # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== function(package_is_activated pkg activated) string(TOUPPER ${pkg} _u_pkg) - set(activated ${AKANTU_HAS_${_u_pkg}} PARENT_SCOPE) + set(${activated} ${AKANTU_HAS_${_u_pkg}} PARENT_SCOPE) endfunction() function(package_get_include_dir pkg include_dir) string(TOUPPER ${pkg} _u_pkg) - set(include_dir ${AKANTU_${_u_pkg}_INCLUDE_DIR} PARENT_SCOPE) + set(${include_dir} ${AKANTU_${_u_pkg}_INCLUDE_DIR} PARENT_SCOPE) endfunction() function(package_get_libraries pkg libs) string(TOUPPER ${pkg} _u_pkg) - set(libs ${AKANTU_${_u_pkg}_LIBRARIES} PARENT_SCOPE) + set(${libs} ${AKANTU_${_u_pkg}_LIBRARIES} PARENT_SCOPE) endfunction() function(package_get_compile_flags pkg lang flags) string(TOUPPER ${pkg} _u_pkg) - set(flags ${AKANTU_${_u_pkg}_COMPILE_${lang}_FLAGS} PARENT_SCOPE) + set(${flags} ${AKANTU_${_u_pkg}_COMPILE_${lang}_FLAGS} PARENT_SCOPE) endfunction() function(get_target_list_of_associated_files tgt files) get_target_property(_type ${tgt} TYPE) if(_type STREQUAL "SHARED_LIBRARY" OR _type STREQUAL "STATIC_LIBRARY" OR _type STREQUAL "MODULE_LIBRARY" OR _type STREQUAL "EXECUTABLE") get_target_property(_srcs ${tgt} SOURCES) set(_dep_ressources) foreach(_file ${_srcs}) list(APPEND _dep_ressources ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) endforeach() else() get_target_property(_dep_ressources ${tgt} RESSOURCES) endif() set(${files} ${_dep_ressources} PARENT_SCOPE) endfunction() diff --git a/cmake/Modules/FindMETIS.cmake b/cmake/Modules/FindMETIS.cmake new file mode 100644 index 000000000..267cf264d --- /dev/null +++ b/cmake/Modules/FindMETIS.cmake @@ -0,0 +1,37 @@ +find_path(METIS_INCLUDE_DIR metis.h + PATHS "${METIS_DIR}" + ENV METIS_DIR + PATH_SUFFIXES include + ) + +find_library(METIS_LIBRARY NAMES metis + PATHS "${METIS_DIR}" + ENV METIS_DIR + PATH_SUFFIXES lib + ) + +mark_as_advanced(METIS_LIBRARY METIS_INCLUDE_DIR) + +#=============================================================================== +include(FindPackageHandleStandardArgs) +if(CMAKE_VERSION VERSION_GREATER 2.8.12) + if(METIS_INCLUDE_DIR) + file(STRINGS ${METIS_INCLUDE_DIR}/metis.h _versions + REGEX "^#define\ +METIS_VER_(MAJOR|MINOR|SUBMINOR) .*") + foreach(_ver ${_versions}) + string(REGEX MATCH "METIS_VER_(MAJOR|MINOR|SUBMINOR) *([0-9.]+)" _tmp "${_ver}") + set(_metis_${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) + endforeach() + set(METIS_VERSION "${_metis_MAJOR}.${_metis_MINOR}" CACHE INTERNAL "") + endif() + + find_package_handle_standard_args(METIS + REQUIRED_VARS + METIS_LIBRARY + METIS_INCLUDE_DIR + VERSION_VAR + METIS_VERSION) +else() + find_package_handle_standard_args(METIS DEFAULT_MSG + METIS_LIBRARY METIS_INCLUDE_DIR) +endif() diff --git a/cmake/Modules/FindMumps.cmake b/cmake/Modules/FindMumps.cmake index 036e58910..89b35a6ae 100644 --- a/cmake/Modules/FindMumps.cmake +++ b/cmake/Modules/FindMumps.cmake @@ -1,182 +1,241 @@ #=============================================================================== # @file FindMumps.cmake # # @author Nicolas Richart # # @date creation: Fri Oct 24 2014 # @date last modification: Wed Jan 13 2016 # # @brief The find_package file for the Mumps solver # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== -set(_MUMPS_COMPONENTS "sequential" "parallel") +set(_MUMPS_COMPONENTS "sequential" "parallel" "double" "float" "complex_double" "complex_float") if(NOT Mumps_FIND_COMPONENTS) - set(Mumps_FIND_COMPONENTS "parallel") + set(Mumps_FIND_COMPONENTS "parallel" "double" "float" "complex_double" "complex_float") endif() #=============================================================================== enable_language(Fortran) -if("${Mumps_FIND_COMPONENTS}" STREQUAL "sequential") - set(MUMPS_PREFIX _seq) -else() - unset(MUMPS_PREFIX) +set(MUMPS_PRECISIONS) +foreach(_comp ${Mumps_FIND_COMPONENTS}) + if("${_comp}" STREQUAL "sequential") + set(MUMPS_PLAT _seq) #default plat on debian based distribution + endif() + + if("${_comp}" STREQUAL "float") + list(APPEND MUMPS_PRECISIONS s) + endif() + if("${_comp}" STREQUAL "double") + list(APPEND MUMPS_PRECISIONS d) + endif() + if("${_comp}" STREQUAL "complex_float") + list(APPEND MUMPS_PRECISIONS c) + endif() + if("${_comp}" STREQUAL "complex_double") + list(APPEND MUMPS_PRECISIONS z) + endif() +endforeach() + +if(NOT MUMPS_PRECISIONS) + set(MUMPS_PRECISIONS s d c z) endif() -find_path(MUMPS_INCLUDE_DIR dmumps_c.h - HINTS ${MUMPS_DIR} - PATH_SUFFIXES include - ) +list(GET MUMPS_PRECISIONS 0 _first_precision) -find_library(MUMPS_LIBRARY_COMMON NAMES mumps_common${MUMPS_PREFIX} - HINTS ${MUMPS_DIR} - PATH_SUFFIXES lib - ) +string(TOUPPER "${_first_precision}" _u_first_precision) -find_library(MUMPS_LIBRARY_PORD NAMES pord${MUMPS_PREFIX} - HINTS ${MUMPS_DIR} - PATH_SUFFIXES lib - ) +set(_mumps_test_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}") +file(WRITE "${_mumps_test_dir}/mumps_test_code.c" + "#include <${_first_precision}mumps_c.h> -foreach(_precision s d c z) +int main() { + ${_u_first_precision}MUMPS_STRUC_C mumps_data; + ${_first_precision}mumps_c(&mumps_data); + return 0; +} +") + + +find_path(MUMPS_INCLUDE_DIR ${_first_precision}mumps_c.h + PATHS "${MUMPS_DIR}" + ENV MUMPS_DIR + PATH_SUFFIXES include + ) + +set(_mumps_required_vars) +foreach(_precision ${MUMPS_PRECISIONS}) string(TOUPPER "${_precision}" _u_precision) find_library(MUMPS_LIBRARY_${_u_precision}MUMPS NAMES ${_precision}mumps${MUMPS_PREFIX} - HINTS ${MUMPS_DIR} /usr + PATHS "${MUMPS_DIR}" + ENV MUMPS_DIR PATH_SUFFIXES lib ) mark_as_advanced(MUMPS_LIBRARY_${_u_precision}MUMPS) -endforeach() + list(APPEND _mumps_required_vars MUMPS_LIBRARY_${_u_precision}MUMPS) -mark_as_advanced( - MUMPS_LIBRARY_COMMON - MUMPS_LIBRARY_PORD - MUMPS_INCLUDE_DIR) + list(APPEND MUMPS_LIBRARIES_ALL ${MUMPS_LIBRARY_${_u_precision}MUMPS}) +endforeach() -#=============================================================================== -if(NOT MUMPS_FOUND) - set(MUMPS_DIR "" CACHE PATH "Prefix of MUMPS library.") - mark_as_advanced(MUMPS_DIR) -endif() #=============================================================================== include(FindPackageHandleStandardArgs) if(CMAKE_VERSION VERSION_GREATER 2.8.12) if(MUMPS_INCLUDE_DIR) file(STRINGS ${MUMPS_INCLUDE_DIR}/dmumps_c.h _versions REGEX "^#define MUMPS_VERSION .*") foreach(_ver ${_versions}) string(REGEX MATCH "MUMPS_VERSION *\"([0-9.]+)\"" _tmp "${_ver}") set(_mumps_VERSION ${CMAKE_MATCH_1}) endforeach() set(MUMPS_VERSION "${_mumps_VERSION}" CACHE INTERNAL "") endif() find_package_handle_standard_args(Mumps REQUIRED_VARS - MUMPS_LIBRARY_DMUMPS - MUMPS_LIBRARY_COMMON - MUMPS_LIBRARY_PORD + ${_mumps_required_vars} MUMPS_INCLUDE_DIR VERSION_VAR MUMPS_VERSION) else() find_package_handle_standard_args(Mumps DEFAULT_MSG - MUMPS_LIBRARIES MUMPS_INCLUDE_DIR) + ${_mumps_required_vars} MUMPS_INCLUDE_DIR) endif() +#=============================================================================== +set(_mumps_dep_symbol_BLAS ${_first_precision}gemm) +set(_mumps_dep_symbol_ScaLAPACK numroc) +set(_mumps_dep_symbol_MPI mpi_send) +set(_mumps_dep_symbol_Scotch scotchfstratinit) +set(_mumps_dep_symbol_Scotch_ptscotch scotchfdgraphexit) +set(_mumps_dep_symbol_Scotch_esmumps esmumps) +set(_mumps_dep_symbol_mumps_common mumps_abort) +set(_mumps_dep_symbol_pord SPACE_ordering) +set(_mumps_dep_symbol_METIS metis_nodend) +set(_mumps_dep_symbol_ParMETIS ParMETIS_V3_NodeND) + +set(_mumps_dep_link_BLAS BLAS_LIBRARIES) +set(_mumps_dep_link_ScaLAPACK SCALAPACK_LIBRARIES) +set(_mumps_dep_link_MPI MPI_Fortran_LIBRARIES) +set(_mumps_dep_link_Scotch SCOTCH_LIBRARIES) +set(_mumps_dep_link_Scotch_ptscotch SCOTCH_LIBRARY_PTSCOTCH) +set(_mumps_dep_link_Scotch_esmumps SCOTCH_LIBRARY_ESMUMPS) +set(_mumps_dep_link_mumps_common MUMPS_LIBRARY_COMMON) +set(_mumps_dep_link_pord MUMPS_LIBRARY_PORD) +set(_mumps_dep_link_METIS METIS_LIBRARY) +set(_mumps_dep_link_ParMETIS PARMETIS_LIBRARY) + +set(_mumps_dep_comp_Scotch_ptscotch COMPONENTS ptscotch) +set(_mumps_dep_comp_Scotch_ptscotch COMPONENTS esmumps) + +set(_mumps_potential_dependencies mumps_common pord BLAS ScaLAPACK MPI + Scotch Scotch_ptscotch Scotch_esmumps METIS ParMETIS) +#=============================================================================== -if (MUMPS_FOUND AND NOT TARGET MUMPS::common) - set(MUMPS_LIBRARIES_ALL ${MUMPS_LIBRARY_DMUMPS}) - - if(MUMPS_LIBRARY_COMMON MATCHES ".*mumps_common.*${CMAKE_STATIC_LIBRARY_SUFFIX}") - # Assuming mumps was compiled as a static library - set(MUMPS_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE) - - set(_extra_dep_list pthread) - find_package(BLAS REQUIRED) - list(APPEND _extra_dep_list ${BLAS_LIBRARIES}) +if(MUMPS_LIBRARY_${_u_first_precision}MUMPS MATCHES ".*${_first_precision}mumps.*${CMAKE_STATIC_LIBRARY_SUFFIX}") + # Assuming mumps was compiled as a static library + set(MUMPS_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE) - if (CMAKE_Fortran_COMPILER MATCHES ".*gfortran") - set(_compiler_specific gfortran) - elseif (CMAKE_Fortran_COMPILER MATCHES ".*ifort") - set(_compiler_specific ifcore) - endif() - list(APPEND _extra_dep_list ${_compiler_specific}) + if (CMAKE_Fortran_COMPILER MATCHES ".*gfortran") + set(_compiler_specific gfortran) + elseif (CMAKE_Fortran_COMPILER MATCHES ".*ifort") + set(_compiler_specific ifcore) + else() + message("Compiler ${CMAKE_Fortran_COMPILER} is not known, you will probably " + "have to add semething instead of this message to be able to test mumps " + "install") + endif() +else() + set(MUMPS_LIBRARY_TYPE SHARED CACHE INTERNAL "" FORCE) +endif() - list(APPEND MUMPS_LIBRARIES_ALL - ${MUMPS_LIBRARY_COMMON} - ${MUMPS_LIBRARY_PORD} - pthread - ${_compiler_specific} - ) +try_compile(_mumps_compiles "${_mumps_test_dir}" SOURCES "${_mumps_test_dir}/mumps_test_code.c" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${MUMPS_INCLUDE_DIR}" + LINK_LIBRARIES ${MUMPS_LIBRARIES_ALL} ${_compiler_specific} + OUTPUT_VARIABLE _out) - if("${Mumps_FIND_COMPONENTS}" STREQUAL "parallel") - find_package(MPI REQUIRED) - list(APPEND _extra_dep_list ${MPI_Fortran_LIBRARIES}) +foreach(_pdep ${_mumps_potential_dependencies}) + if(_mumps_compiles) + break() + endif() - find_package(ScaLAPACK REQUIRED) - list(APPEND _extra_dep_list ScaLAPACK) + if(_out MATCHES "${_mumps_dep_symbol_${_pdep}}") + if(_pdep STREQUAL "mumps_common") + find_library(MUMPS_LIBRARY_COMMON mumps_common${MUMPS_PREFIX} + PATHS "${MUMPS_DIR}" + ENV MUMPS_DIR + PATH_SUFFIXES lib + ) - list(APPEND MUMPS_LIBRARIES_ALL - ${MPI_Fortran_LIBRARIES} - ${SCALAPACK_LIBRARIES} + if(NOT TARGET MUMPS::common) + add_library(MUMPS::common ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(MUMPS::common PROPERTIES + IMPORTED_LOCATION "${MUMPS_LIBRARY_COMMON}" + INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran") + list(APPEND _mumps_interface_link MUMPS::common) + elseif(_pdep STREQUAL "pord") + find_library(MUMPS_LIBRARY_PORD pord${MUMPS_PREFIX} + PATHS "${MUMPS_DIR}" + ENV MUMPS_DIR + PATH_SUFFIXES lib ) + if(NOT TARGET MUMPS::pord) + add_library(MUMPS::pord ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + #TODO adapt it for windows and dlls (check FindGSL as an example) + set_target_properties(MUMPS::pord PROPERTIES + IMPORTED_LOCATION "${MUMPS_LIBRARY_PORD}" + INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + list(APPEND _mumps_interface_link MUMPS::pord) + elseif(_pdep MATCHES "Scotch") + find_package(Scotch REQUIRED ${_mumps_dep_comp_${_pdep}}) + list(APPEND _mumps_interface_link ${${_mumps_dep_link_${_pdep}}}) + else() + find_package(${_pdep} REQUIRED) + list(APPEND _mumps_interface_link ${${_mumps_dep_link_${_pdep}}}) endif() - list(APPEND MUMPS_LIBRARIES_ALL - ${BLAS_LIBRARIES}) + list(APPEND MUMPS_LIBRARIES_ALL ${${_mumps_dep_link_${_pdep}}}) - if(_extra_dep_list) - set(_extra_dep ";${_extra_dep_list}") - else() - set(_extra_dep) - endif() - else() - set(MUMPS_LIBRARY_TYPE SHARED CACHE INTERNAL "" FORCE) + try_compile(_mumps_compiles "${_mumps_test_dir}" SOURCES "${_mumps_test_dir}/mumps_test_code.c" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${MUMPS_INCLUDE_DIR}" + LINK_LIBRARIES ${MUMPS_LIBRARIES_ALL} ${_compiler_specific} + OUTPUT_VARIABLE _out) endif() +endforeach() - add_library(MUMPS::common ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) - add_library(MUMPS::pord ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) - - #TODO adapt it for windows and dlls (check FindGSL as an example) - set_target_properties(MUMPS::pord PROPERTIES - IMPORTED_LOCATION "${MUMPS_LIBRARY_PORD}" - INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C") - set_target_properties(MUMPS::common PROPERTIES - IMPORTED_LOCATION "${MUMPS_LIBRARY_COMMON}" +foreach(_precision ${MUMPS_PRECISIONS}) + string(TOUPPER "${_precision}" _u_precision) + set(_target MUMPS::${_precision}mumps) + if(NOT TARGET ${_target}) + add_library(${_target} ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(${_target} PROPERTIES + IMPORTED_LOCATION "${MUMPS_LIBRARY_${_u_precision}MUMPS}" INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran" - INTERFACE_LINK_LIBRARIES "MUMPS::pord${_extra_dep}") + INTERFACE_LINK_LIBRARIES "${_mumps_interface_link}") +endforeach() - foreach(_precision s d c z) - string(TOUPPER "${_precision}" _u_precision) - set(_target MUMPS::${_precision}mumps) - add_library(${_target} ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL) - set_target_properties(${_target} PROPERTIES - IMPORTED_LOCATION "${MUMPS_LIBRARY_${_u_precision}MUMPS}" - INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran" - INTERFACE_LINK_LIBRARIES "MUMPS::common") - endforeach() - - set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE) -endif() +set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "" FORCE) diff --git a/cmake/Modules/FindPETSc.cmake b/cmake/Modules/FindPETSc.cmake index 6dbfc4916..ac83daed7 100644 --- a/cmake/Modules/FindPETSc.cmake +++ b/cmake/Modules/FindPETSc.cmake @@ -1,334 +1,329 @@ # - Try to find PETSc # Once done this will define # # PETSC_FOUND - system has PETSc # PETSC_INCLUDES - the PETSc include directories # PETSC_LIBRARIES - Link these to use PETSc # PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI # PETSC_DEFINITIONS - Compiler switches for using PETSc # PETSC_MPIEXEC - Executable for running MPI programs # PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR) # # Usage: # find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 # find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler # find_package(PETSc) - same as above # # Setting these changes the behavior of the search # PETSC_DIR - directory in which PETSc resides # PETSC_ARCH - build architecture # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # set(PETSC_VALID_COMPONENTS C CXX) if(NOT PETSc_FIND_COMPONENTS) set(PETSC_LANGUAGE_BINDINGS "C") else() # Right now, this is designed for compatability with the --with-clanguage option, so # only allow one item in the components list. list(LENGTH ${PETSc_FIND_COMPONENTS} components_length) if(${components_length} GREATER 1) message(FATAL_ERROR "Only one component for PETSc is allowed to be specified") endif() # This is a stub for allowing multiple components should that time ever come. Perhaps # to also test Fortran bindings? foreach(component ${PETSc_FIND_COMPONENTS}) list(FIND PETSC_VALID_COMPONENTS ${component} component_location) if(${component_location} EQUAL -1) message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.") else() list(APPEND PETSC_LANGUAGE_BINDINGS ${component}) endif() endforeach() endif() function (petsc_get_version) if (EXISTS "${PETSC_DIR}/include/petscversion.h") file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ") foreach (line ${vstrings}) string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define") list (GET fields 1 var) list (GET fields 2 val) set (${var} ${val} PARENT_SCOPE) set (${var} ${val}) # Also in local scope so we have access below endforeach () if (PETSC_VERSION_RELEASE) set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE) else () # make dev version compare higher than any patch level of a released version set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE) endif () else () message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist") endif () endfunction () find_path (PETSC_DIR include/petsc.h HINTS ENV PETSC_DIR PATHS # Debian paths /usr/lib/petscdir/3.5.1 /usr/lib/petscdir/3.5 /usr/lib/petscdir/3.4.2 /usr/lib/petscdir/3.4 /usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1 /usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2 # MacPorts path /opt/local/lib/petsc $ENV{HOME}/petsc DOC "PETSc Directory") find_program (MAKE_EXECUTABLE NAMES make gmake) if (PETSC_DIR AND NOT PETSC_ARCH) set (_petsc_arches $ENV{PETSC_ARCH} # If set, use environment variable first linux-gnu-c-debug linux-gnu-c-opt # Debian defaults x86_64-unknown-linux-gnu i386-unknown-linux-gnu) set (petscconf "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) foreach (arch ${_petsc_arches}) if (NOT PETSC_ARCH) find_path (petscconf petscconf.h HINTS ${PETSC_DIR} PATH_SUFFIXES ${arch}/include bmake/${arch} NO_DEFAULT_PATH) if (petscconf) set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture") endif (petscconf) endif (NOT PETSC_ARCH) endforeach (arch) set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) endif (PETSC_DIR AND NOT PETSC_ARCH) set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS INCLUDE_DIR INCLUDE_CONF) include (FindPackageMultipass) find_package_multipass (PETSc petsc_config_current STATES DIR ARCH DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves}) # Determine whether the PETSc layout is old-style (through 2.3.3) or # new-style (>= 3.0.0) if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscvariables") # > 3.5 set (petsc_conf_rules "${PETSC_DIR}/lib/petsc/conf/rules") set (petsc_conf_variables "${PETSC_DIR}/lib/petsc/conf/variables") elseif (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3 set (petsc_conf_rules "${PETSC_DIR}/conf/rules") set (petsc_conf_variables "${PETSC_DIR}/conf/variables") elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3 set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules") set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables") elseif (PETSC_DIR) message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation") endif () - -#message(petsc_conf_rules ${petsc_conf_rules}) -#message(petsc_conf_variables ${petsc_conf_variables}) -#message(petsc_config_current ${petsc_config_current}) - if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) petsc_get_version() # Put variables into environment since they are needed to get # configuration (petscvariables) in the PETSc makefile set (ENV{PETSC_DIR} "${PETSC_DIR}") set (ENV{PETSC_ARCH} "${PETSC_ARCH}") # A temporary makefile to probe the PETSc configuration set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") file (WRITE "${petsc_config_makefile}" "## This file was autogenerated by FindPETSc.cmake # PETSC_DIR = ${PETSC_DIR} # PETSC_ARCH = ${PETSC_ARCH} include ${petsc_conf_rules} include ${petsc_conf_variables} show : \t-@echo -n \${\${VARIABLE}} ") macro (PETSC_GET_VARIABLE name var) set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name} OUTPUT_VARIABLE ${var} RESULT_VARIABLE petsc_return) endmacro (PETSC_GET_VARIABLE) petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir) petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external) petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line) petsc_get_variable (PETSC_INCLUDE petsc_include) petsc_get_variable (PCC petsc_cc) petsc_get_variable (PCC_FLAGS petsc_cc_flags) petsc_get_variable (MPIEXEC petsc_mpiexec) # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! file (REMOVE ${petsc_config_makefile}) include (ResolveCompilerPaths) # Extract include paths and libraries from compile command line resolve_includes (petsc_includes_all "${petsc_cpp_line}") #on windows we need to make sure we're linking against the right #runtime library if (WIN32) if (petsc_cc_flags MATCHES "-MT") set(using_md False) foreach(flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if(${flag_var} MATCHES "/MD") set(using_md True) endif(${flag_var} MATCHES "/MD") endforeach(flag_var) if(${using_md} MATCHES "True") message(WARNING "PETSc was built with /MT, but /MD is currently set. See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F") endif(${using_md} MATCHES "True") endif (petsc_cc_flags MATCHES "-MT") endif (WIN32) include (CorrectWindowsPaths) convert_cygwin_path(petsc_lib_dir) message (STATUS "petsc_lib_dir ${petsc_lib_dir}") macro (PETSC_FIND_LIBRARY suffix name) set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again if (WIN32) set (libname lib${name}) #windows expects "libfoo", linux expects "foo" else (WIN32) set (libname ${name}) endif (WIN32) find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH) set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}") mark_as_advanced (PETSC_LIBRARY_${suffix}) endmacro (PETSC_FIND_LIBRARY suffix name) # Look for petscvec first, if it doesn't exist, we must be using single-library petsc_find_library (VEC petscvec) if (PETSC_LIBRARY_VEC) petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) petsc_find_library (MAT petscmat) petsc_find_library (DM petscdm) petsc_find_library (KSP petscksp) petsc_find_library (SNES petscsnes) petsc_find_library (TS petscts) macro (PETSC_JOIN libs deps) list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) endmacro (PETSC_JOIN libs deps) petsc_join (VEC SYS) petsc_join (MAT VEC) petsc_join (DM MAT) petsc_join (KSP DM) petsc_join (SNES KSP) petsc_join (TS SNES) petsc_join (ALL TS) else () set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec petsc_find_library (SINGLE petsc) foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}") endforeach () endif () if (PETSC_LIBRARY_TS) message (STATUS "Recognized PETSc install with separate libraries for each package") else () message (STATUS "Recognized PETSc install with single library for all packages") endif () include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns) macro (PETSC_TEST_RUNS includes libraries runs) if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C") set(_PETSC_ERR_FUNC "CHKERRQ(ierr)") elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX") set(_PETSC_ERR_FUNC "CHKERRXX(ierr)") endif() if (PETSC_VERSION VERSION_GREATER 3.1) set (_PETSC_TSDestroy "TSDestroy(&ts)") else () set (_PETSC_TSDestroy "TSDestroy(ts)") endif () set(_PETSC_TEST_SOURCE " static const char help[] = \"PETSc test program.\"; #include int main(int argc,char *argv[]) { PetscErrorCode ierr; TS ts; ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC}; ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC}; ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC}; ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC}; ierr = PetscFinalize();${_PETSC_ERR_FUNC}; return 0; } ") multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}") if (${${runs}}) set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL "Can the system successfully run a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration, but this will almost always result in a broken build. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE) endif (${${runs}}) endmacro (PETSC_TEST_RUNS) find_path (PETSC_INCLUDE_DIR petscts.h HINTS "${PETSC_DIR}" PATH_SUFFIXES include NO_DEFAULT_PATH) find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_DIR}" PATH_SUFFIXES "${PETSC_ARCH}/include" "bmake/${PETSC_ARCH}" NO_DEFAULT_PATH) mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF) set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal) if (petsc_works_minimal) message (STATUS "Minimal PETSc includes and libraries work. This probably means we are building with shared libs.") set (petsc_includes_needed "${petsc_includes_minimal}") else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes) if (petsc_works_allincludes) # It does, we just need all the includes ( message (STATUS "PETSc requires extra include paths, but links correctly with only interface libraries. This is an unexpected configuration (but it seems to work fine).") set (petsc_includes_needed ${petsc_includes_all}) else (petsc_works_allincludes) # We are going to need to link the external libs explicitly resolve_libraries (petsc_libraries_external "${petsc_libs_external}") foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) endforeach (pkg) petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries) if (petsc_works_alllibraries) message (STATUS "PETSc only need minimal includes, but requires explicit linking to all dependencies. This is expected when PETSc is built with static libraries.") set (petsc_includes_needed ${petsc_includes_minimal}) else (petsc_works_alllibraries) # It looks like we really need everything, should have listened to Matt set (petsc_includes_needed ${petsc_includes_all}) petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all) if (petsc_works_all) # We fail anyways message (STATUS "PETSc requires extra include paths and explicit linking to all dependencies. This probably means you have static libraries and something unexpected in PETSc headers.") else (petsc_works_all) # We fail anyways message (STATUS "PETSc could not be used, maybe the install is broken.") endif (petsc_works_all) endif (petsc_works_alllibraries) endif (petsc_works_allincludes) endif (petsc_works_minimal) # We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous if (${PETSC_VERSION} VERSION_LESS 3.1) set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSc definitions" FORCE) else () set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE) endif () # Sometimes this can be used to assist FindMPI.cmake set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSc MPI programs" FORCE) set (PETSC_INCLUDES ${petsc_includes_needed} CACHE STRING "PETSc include path" FORCE) set (PETSC_LIBRARIES ${PETSC_LIBRARIES_ALL} CACHE STRING "PETSc libraries" FORCE) set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSc compiler" FORCE) # Note that we have forced values for all these choices. If you # change these, you are telling the system to trust you that they # work. It is likely that you will end up with a broken build. mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS) endif () include (FindPackageHandleStandardArgs) find_package_handle_standard_args (PETSc "PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH." PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXECUTABLE_RUNS) diff --git a/cmake/Modules/FindParMETIS.cmake b/cmake/Modules/FindParMETIS.cmake new file mode 100644 index 000000000..a105cc9af --- /dev/null +++ b/cmake/Modules/FindParMETIS.cmake @@ -0,0 +1,37 @@ +find_path(PARMETIS_INCLUDE_DIR parmetis.h + PATHS "${PARMETIS_DIR}" + ENV PARMETIS_DIR + PATH_SUFFIXES include + ) + +find_library(PARMETIS_LIBRARY NAMES parmetis + PATHS "${PARMETIS_DIR}" + ENV PARMETIS_DIR + PATH_SUFFIXES lib + ) + +mark_as_advanced(PARMETIS_LIBRARY PARMETIS_INCLUDE_DIR) + +#=============================================================================== +include(FindPackageHandleStandardArgs) +if(CMAKE_VERSION VERSION_GREATER 2.8.12) + if(PARMETIS_INCLUDE_DIR) + file(STRINGS ${PARMETIS_INCLUDE_DIR}/parmetis.h _versions + REGEX "^#define\ +PARMETIS_(MAJOR|MINOR|SUBMINOR)_VERSION .*") + foreach(_ver ${_versions}) + string(REGEX MATCH "PARMETIS_(MAJOR|MINOR|SUBMINOR)_VERSION *([0-9.]+)" _tmp "${_ver}") + set(_parmetis_${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) + endforeach() + set(PARMETIS_VERSION "${_parmetis_MAJOR}.${_parmetis_MINOR}" CACHE INTERNAL "") + endif() + + find_package_handle_standard_args(ParMETIS + REQUIRED_VARS + PARMETIS_LIBRARY + PARMETIS_INCLUDE_DIR + VERSION_VAR + PARMETIS_VERSION) +else() + find_package_handle_standard_args(ParMETIS DEFAULT_MSG + PARMETIS_LIBRARY PARMETIS_INCLUDE_DIR) +endif() diff --git a/cmake/Modules/FindScaLAPACK.cmake b/cmake/Modules/FindScaLAPACK.cmake index b2f203f52..b0ffabc36 100644 --- a/cmake/Modules/FindScaLAPACK.cmake +++ b/cmake/Modules/FindScaLAPACK.cmake @@ -1,116 +1,117 @@ #=============================================================================== # @file FindScaLAPACK.cmake # # @author Nicolas Richart # # @date creation: Tue Mar 31 2015 # @date last modification: Wed Jan 13 2016 # # @brief The find_package file for the Mumps solver # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== find_library(SCALAPACK_LIBRARY NAME scalapack - HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib) + PATHS "${SCALAPACK_DIR}" ENV SCALAPACK_DIR PATH_SUFFIXES lib) mark_as_advanced(SCALAPACK_LIBRARY) -#=============================================================================== -if(NOT SCALAPACK_FOUND) - set(SCALAPACK_DIR "" CACHE PATH "Prefix of MUMPS library.") - mark_as_advanced(SCALAPACK_DIR) -endif() - #=============================================================================== include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ScaLAPACK DEFAULT_MSG SCALAPACK_LIBRARY) if(SCALAPACK_FOUND AND NOT TARGET ScaLAPACK) set(SCALAPACK_LIBRARIES_ALL ${SCALAPACK_LIBRARY}) + + include(CheckFortranFunctionExists) + set(CMAKE_REQUIRED_LIBRARIES ${SCALAPACK_LIBRARIES_ALL}) + check_fortran_function_exists("blacs_gridinit" SCALAPACK_DOES_NOT_NEED_BLACS) + set(CMAKE_REQUIRED_LIBRARIES) + + set(_blacs_dep) - if(SCALAPACK_LIBRARY MATCHES ".*scalapack.*${CMAKE_STATIC_LIBRARY_SUFFIX}") + if(NOT SCALAPACK_DOES_NOT_NEED_BLACS) # Assuming scalapack was compiled as a static library set(SCALAPACK_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE) find_library(BLACS_LIBRARY_C NAME blacsC - HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib) + PATHS "${SCALAPACK_DIR}" ENV SCALAPACK_DIR PATH_SUFFIXES lib) find_library(BLACS_LIBRARY_F77 NAME blacsF77 - HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib) + PATHS "${SCALAPACK_DIR}" ENV SCALAPACK_DIR PATH_SUFFIXES lib) find_library(BLACS_LIBRARY NAME blacs - HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib) + PATHS "${SCALAPACK_DIR}" ENV SCALAPACK_DIR PATH_SUFFIXES lib) mark_as_advanced( BLACS_LIBRARY_C BLACS_LIBRARY_F77 BLACS_LIBRARY ) find_package_handle_standard_args(BLACS DEFAULT_MSG BLACS_LIBRARY BLACS_LIBRARY_C BLACS_LIBRARY_F77) add_library(blacs::common ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL) add_library(blacs::F77 ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL) add_library(blacs::C ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL) set_target_properties(blacs::F77 PROPERTIES IMPORTED_LOCATION "${BLACS_LIBRARY_F77}" IMPORTED_LINK_INTERFACE_LANGUAGES "Fortran" INTERFACE_LINK_LIBRARIES blacs::common ) set_target_properties(blacs::C PROPERTIES IMPORTED_LOCATION "${BLACS_LIBRARY_C}" INTERFACE_INCLUDE_DIRECTORIES "${SCALAPACK_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LANGUAGES "C" INTERFACE_LINK_LIBRARIES blacs::common ) set_target_properties(blacs::common PROPERTIES IMPORTED_LOCATION "${BLACS_LIBRARY}" IMPORTED_LINK_INTERFACE_LANGUAGES "C Fortran" INTERFACE_LINK_LIBRARIES "blacs::C;blacs::F77" ) find_package(LAPACK REQUIRED) find_package(BLAS REQUIRED) list(APPEND SCALAPACK_LIBRARIES_ALL ${BLACS_LIBRARY} ${BLACS_LIBRARY_C} ${BLACS_LIBRARY_F77} ${BLACS_LIBRARY} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES}) set(_blacs_dep "blacs::common;${BLAS_LIBRARIES};${LAPACK_LIBRAIES}") else() set(SCALAPACK_LIBRARY_TYPE SHARED) endif() add_library(ScaLAPACK ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL) set_target_properties(ScaLAPACK PROPERTIES IMPORTED_LOCATION "${SCALAPACK_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${SCALAPACK_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LANGUAGES "C Fortran" INTERFACE_LINK_LIBRARIES "${_blacs_dep}") - set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARIES_ALL} CACHE INTERNAL "Libraries for ScaLAPACK" FORCE) + set(SCALAPACK_LIBRARIES ScaLAPACK CACHE INTERNAL "Libraries for ScaLAPACK" FORCE) endif() diff --git a/cmake/Modules/FindScotch.cmake b/cmake/Modules/FindScotch.cmake index b73aa3cdd..c93176451 100644 --- a/cmake/Modules/FindScotch.cmake +++ b/cmake/Modules/FindScotch.cmake @@ -1,92 +1,245 @@ #=============================================================================== # @file FindScotch.cmake # # @author Nicolas Richart # # @date creation: Fri Oct 24 2014 # @date last modification: Wed Jan 13 2016 # # @brief The find_package file for Scotch # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== -#=============================================================================== -if(NOT DEFINED SCOTCH_DIR OR NOT SCOTCH_DIR) - set(SCOTCH_DIR "" CACHE PATH "Location of Scotch library.") -endif() -mark_as_advanced(SCOTCH_DIR) +set(_SCOTCH_COMPONENTS "metis" "parmetis" "esmumps" "ptscotch") -find_library(SCOTCH_LIBRARY scotch PATHS ${SCOTCH_DIR}/lib) -find_library(SCOTCH_LIBRARY_ERR scotcherr PATHS ${SCOTCH_DIR}/lib) -find_library(SCOTCH_LIBRARY_ERREXIT scotcherrexit PATHS ${SCOTCH_DIR}/lib) -find_library(SCOTCH_LIBRARY_ESMUMPS esmumps PATHS ${SCOTCH_DIR}/lib) -find_library(SCOTCH_LIBRARY_METIS scotchmetis PATHS ${SCOTCH_DIR}/lib) -find_library(SCOTCH_LIBRARY_PARMETIS scotchparmetis PATHS ${SCOTCH_DIR}/lib) +if(NOT Scotch_FIND_COMPONENTS) + set(Scotch_FIND_COMPONENTS) +endif() -find_path(SCOTCH_INCLUDE_DIR scotch.h PATHS ${SCOTCH_DIR} +find_path(SCOTCH_INCLUDE_DIR scotch.h PATHS "${SCOTCH_DIR}" ENV SCOTCH_DIR PATH_SUFFIXES include include/scotch ) -#=============================================================================== -mark_as_advanced(SCOTCH_LIBRARY - SCOTCH_LIBRARY_ERR - SCOTCH_LIBRARY_ERREXIT - SCOTCH_LIBRARY_ESMUMPS - SCOTCH_LIBRARY_PARMETIS - SCOTCH_LIBRARY_METIS - SCOTCH_INCLUDE_DIR) - -set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY} ${SCOTCH_LIBRARY_ERR}) - -if(SCOTCH_LIBRARY_ESMUMPS) - set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_ESMUMPS} ${SCOTCH_LIBRARIES_ALL}) -endif() - -if(SCOTCH_LIBRARY_METIS) - set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_METIS} ${SCOTCH_LIBRARIES_ALL}) -endif() -if(SCOTCH_LIBRARY_PARMETIS) - set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_PARMETIS} ${SCOTCH_LIBRARIES_ALL}) -endif() +find_library(SCOTCH_LIBRARY scotch PATHS "${SCOTCH_DIR}" ENV SCOTCH_DIR PATH_SUFFIXES lib) +set(_scotch_test_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}") +file(WRITE "${_scotch_test_dir}/scotch_test_code.c" + "#include +#include +#include -set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE) +int main() { + SCOTCH_Graph graph; + SCOTCH_graphInit(&graph); + return 0; +} +") #=============================================================================== include(FindPackageHandleStandardArgs) if(CMAKE_VERSION VERSION_GREATER 2.8.12) if(SCOTCH_INCLUDE_DIR) file(STRINGS ${SCOTCH_INCLUDE_DIR}/scotch.h _versions REGEX "^#define\ +SCOTCH_(VERSION|RELEASE|PATCHLEVEL) .*") foreach(_ver ${_versions}) string(REGEX MATCH "SCOTCH_(VERSION|RELEASE|PATCHLEVEL) *([0-9.]+)" _tmp "${_ver}") set(_scotch_${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) endforeach() - set(SCOTCH_VERSION "${_scotch_VERSION}.${_scotch_PATCHLEVEL}" CACHE INTERNAL "") + set(SCOTCH_VERSION "${_scotch_VERSION}.${_scotch_RELEASE}.${_scotch_PATCHLEVEL}" CACHE INTERNAL "") endif() find_package_handle_standard_args(Scotch - REQUIRED_VARS SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR + REQUIRED_VARS SCOTCH_LIBRARY SCOTCH_INCLUDE_DIR VERSION_VAR SCOTCH_VERSION) else() find_package_handle_standard_args(Scotch DEFAULT_MSG - SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR) + SCOTCH_LIBRARY SCOTCH_INCLUDE_DIR) +endif() + +set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY}) + +try_compile(_scotch_compiles "${_scotch_test_dir}" SOURCES "${_scotch_test_dir}/scotch_test_code.c" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${SCOTCH_INCLUDE_DIR}" + LINK_LIBRARIES ${SCOTCH_LIBRARY} + OUTPUT_VARIABLE _out) + +get_filename_component(_scotch_hint "${SCOTCH_LIBRARY}" DIRECTORY) + +if(SCOTCH_LIBRARY MATCHES ".*scotch.*${CMAKE_STATIC_LIBRARY_SUFFIX}") + # Assuming scotch was compiled as a static library + set(SCOTCH_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE) +else() + set(SCOTCH_LIBRARY_TYPE SHARED CACHE INTERNAL "" FORCE) +endif() + +if(NOT _scotch_compiles) + if(_out MATCHES "SCOTCH_errorPrint") + find_library(SCOTCH_LIBRARY_ERR scotcherr + HINTS ${_scotch_hint}) + find_library(SCOTCH_LIBRARY_ERREXIT scotcherrexit + HINTS ${_scotch_hint}) + + if(NOT TARGET Scotch::err) + add_library(Scotch::err ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + if(NOT TARGET Scotch::errexit) + add_library(Scotch::errexit ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + + set_target_properties(Scotch::errexit PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_ERREXIT}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + + set_target_properties(Scotch::err PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_ERR}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_LINK_LIBRARIES "Scotch::errexit") + + mark_as_advanced(SCOTCH_LIBRARY_ERR + SCOTCH_LIBRARY_ERREXIT) + + list(APPEND SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_ERR} ${SCOTCH_LIBRARY_ERREXIT}) + + set(_scotch_link_lib INTERFACE_LINK_LIBRARIES "Scotch::err") + endif() +endif() + +if(NOT TARGET Scotch::scotch) + add_library(Scotch::scotch ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) +endif() +set_target_properties(Scotch::scotch PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + ${_scotch_link_lib}) + +set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for Scotch" FORCE) + +mark_as_advanced(SCOTCH_LIBRARY + SCOTCH_INCLUDE_DIR + SCOTCH_LIBRARIES) + + +if("${Scotch_FIND_COMPONENTS}" MATCHES "esmumps") + find_library(SCOTCH_LIBRARY_ESMUMPS esmumps HINTS ${_scotch_hint}) + + if(NOT TARGET Scotch::esmumps) + add_library(Scotch::esmumps ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(Scotch::esmumps PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_ESMUMPS}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + + + mark_as_advanced(SCOTCH_LIBRARY_ESMUMPS) +endif() + +if("${Scotch_FIND_COMPONENTS}" MATCHES "metis") + find_library(SCOTCH_LIBRARY_METIS scotchmetis HINTS ${_scotch_hint}) + + if(NOT TARGET Scotch::metis) + add_library(Scotch::metis ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(Scotch::metis PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_METIS}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + + mark_as_advanced(SCOTCH_LIBRARY_METIS) +endif() + +if("${Scotch_FIND_COMPONENTS}" MATCHES "parmetis") + find_library(SCOTCH_LIBRARY_PARMETIS scotchparmetis HINTS ${_scotch_hint}) + + if(NOT TARGET Scotch::parmetis) + add_library(Scotch::parmetis ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(Scotch::parmetis PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_PARMETIS}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_INCLUDE_DIRECTORIES "Scotch::metis") + mark_as_advanced(SCOTCH_LIBRARY_PARMETIS) +endif() + +# +##=============================================================================== +if("${Scotch_FIND_COMPONENTS}" MATCHES "ptscotch") + file(WRITE "${_scotch_test_dir}/ptscotch_test_code.c" + "#include +#include +#include +#include + +int main() { + SCOTCH_Dgraph graph; + SCOTCH_dgraphInit(&graph, MPI_COMM_WORLD); + return 0; +} +") + + find_package(MPI REQUIRED) + + find_library(SCOTCH_LIBRARY_PTSCOTCH ptscotch HINTS ${_scotch_hint}) + + try_compile(_scotch_compiles "${_scotch_test_dir}" SOURCES "${_scotch_test_dir}/ptscotch_test_code.c" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${SCOTCH_INCLUDE_DIR};${MPI_C_INCLUDE_PATH}" + LINK_LIBRARIES ${SCOTCH_LIBRARY_PTSCOTCH} ${MPI_C_LIBRARIES} + OUTPUT_VARIABLE _out) + + if(NOT _scotch_compiles) + if(_out MATCHES "SCOTCH_archExit") + set(_scotch_link_lib INTERFACE_LINK_LIBRARIES "Scotch::scotch") + endif() + endif() + + if(NOT TARGET Scotch::ptscotch) + add_library(Scotch::ptscotch ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(Scotch::ptscotch PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_PTSCOTCH}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + ${_scotch_link_lib}) + + set(PTSCOTCH_LIBRARIES ${SCOTCH_LIBRARY_PTSCOTCH} ${SCOTCH_LIBRARIES} CACHE INTERNAL "Libraries for PT-Scotch" FORCE) + + mark_as_advanced(SCOTCH_LIBRARY_PTSCOTCH + PTSCOTCH_LIBRARIES) + + if("${Scotch_FIND_COMPONENTS}" MATCHES "esmumps") + find_library(SCOTCH_LIBRARY_PTESMUMPS ptesmumps + HINTS ${_scotch_hint} PATH_SUFFIXES lib .) + + if(NOT TARGET Scotch::ptesmumps) + add_library(Scotch::ptesmumps ${SCOTCH_LIBRARY_TYPE} IMPORTED GLOBAL) + endif() + set_target_properties(Scotch::ptesmumps PROPERTIES + IMPORTED_LOCATION "${SCOTCH_LIBRARY_ESMUMPS}" + INTERFACE_INCLUDE_DIRECTORIES "${SCOTCH_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + + mark_as_advanced(SCOTCH_LIBRARY_PTESMUMPS) + endif() endif() diff --git a/cmake/akantu-debug.cc.in b/cmake/akantu-debug.cc.in new file mode 100644 index 000000000..a7c3952c8 --- /dev/null +++ b/cmake/akantu-debug.cc.in @@ -0,0 +1,7 @@ +/* Note: The "MS" section flags are to remove duplicates. */ +__asm__( + ".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n" + ".byte 1 /* Python */\n" + " .asciz \"@PROJECT_BINARY_DIR@/libakantu-gdb.py\"\n" + ".popsection\n" + ); diff --git a/cmake/libakantu-gdb.py.in b/cmake/libakantu-gdb.py.in new file mode 100644 index 000000000..1d441ac75 --- /dev/null +++ b/cmake/libakantu-gdb.py.in @@ -0,0 +1,8 @@ +# -*- python -*- +import sys + +libdir = '@AKANTU_GDB_DIR@' +sys.path.append(libdir) + +import libakantu.v2 + diff --git a/cmake/libakantu/__init__.py b/cmake/libakantu/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/libakantu/v2/__init__.py b/cmake/libakantu/v2/__init__.py new file mode 100644 index 000000000..cc2c5a24e --- /dev/null +++ b/cmake/libakantu/v2/__init__.py @@ -0,0 +1,5 @@ +import gdb + +# Load the pretty-printers. +from .printers import register_akantu_printers +register_akantu_printers(gdb.current_objfile()) diff --git a/cmake/libakantu/v2/printers.py b/cmake/libakantu/v2/printers.py new file mode 100755 index 000000000..1dae8062a --- /dev/null +++ b/cmake/libakantu/v2/printers.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# encoding: utf-8 +# +# Inspired from boost's pretty printers from Rüdiger Sonderfeld +# and from Pretty-printers for libstc++ from Free Software Foundation, Inc. +# + +import gdb +import itertools +import numpy +import re +#import libstdcxx.v6.printers as std + +__use_gdb_pp__ = True +try: + import gdb.printing +except ImportError: + __use_gdb_pp__ = False + + +class AkantuPrinter(object): + regex = None + + @classmethod + def supports(cls, typename): + return cls.regex.search(typename) + + @classmethod + def get_basic_type(cls, value): + """ Determines the type associated to a value""" + + _type = value.type + # If it points to a reference, get the reference. + if _type.code == gdb.TYPE_CODE_REF: + _type = _type.target () + + # Get the unqualified type, stripped of typedefs. + _type = _type.unqualified().strip_typedefs() + + return _type.tag + +if __use_gdb_pp__: + __akantu_pretty_printers__ = gdb.printing.RegexpCollectionPrettyPrinter("libakantu-v2") +else: + class AkantuPrettyPrinters(object): + def __init__(self, name): + super(AkantuPrettyPrinters, self).__init__() + self.name = name + self.printers = {} + + def add_printer(self, name, regex, printer): + self.printers[name] = printer + + def __call__(self, val): + typename = AkantuPrinter.get_basic_type(val) + if not typename: + return None + + for name, printer in self.printers.iteritems(): + if(printer.supports(typename)): + return printer + + return None + + __akantu_pretty_printers__ = AkantuPrettyPrinters("libakantu-v2") + + +def register_pretty_printer(pretty_printer): + "Registers a Pretty Printer" + + __akantu_pretty_printers__.add_printer(pretty_printer.name, + pretty_printer.regex, + pretty_printer) + + return pretty_printer + +@register_pretty_printer +class AkaTensorPrinter(AkantuPrinter): + """Pretty printer for akantu::Tensor""" + regex = re.compile('^akantu::Tensor<(.*), +(.*), +(.*)>$') + name = 'akantu::Tensor' + + value = None + typename = "" + ptr = None + dims = [] + ndims = 0 + + def pretty_print(self): + def ij2str(i, j, m): + return "{0}".format((self.ptr+m*j + i).dereference()) + def line(i, m, n): + return "[{0}]".format(", ".join((ij2str(i,j, m) for j in range(n)))) + + m = int(self.dims[0]) + if (self.ndims == 1): + n = 1 + else: + n = int(self.dims[1]) + + return "[{0}]".format(", ".join(line(i, m, n) for i in range(m))) + + def __init__(self, value): + self.typename = self.get_basic_type(value) + self.value = value + self.ptr = self.value['values'] + self.dims = self.value['n'] + + def children(self): + yield ('values', self.pretty_print()) + yield ('wrapped', self.value['wrapped']) + + +@register_pretty_printer +class AkaVectorPrinter(AkaTensorPrinter): + """Pretty printer for akantu::Vector""" + regex = re.compile('^akantu::Vector<(.*)>$') + name = 'akantu::Vector' + n = 0 + ptr = 0x0 + + def __init__(self, value): + super(AkaVectorPrinter, self).__init__(value) + self.ndims = 1 + + def to_string (self): + m = self.regex.search(self.typename) + return 'Vector<{0}>({1}) [{2}]'.format(m.group(1), int(self.dims[0]), + str(self.ptr)) + +@register_pretty_printer +class AkaMatrixPrinter(AkaTensorPrinter): + """Pretty printer for akantu::Matrix""" + regex = re.compile('^akantu::Matrix<(.*)>$'); + name = 'akantu::Matrix'; + + def __init__(self, value): + super(AkaMatrixPrinter, self).__init__(value) + self.ndims = 2 + + def to_string (self): + m = self.regex.search(self.typename) + return 'Matrix<%s>(%d, %d) [%s]' % (m.group(1), int(self.dims[0]), + int(self.dims[1]), + str(self.ptr)) + +@register_pretty_printer +class AkaElementPrinter(AkantuPrinter): + """Pretty printer for akantu::Element""" + regex = re.compile('^akantu::Element$') + name = 'akantu::Element' + + def __init__(self, value): + self.typename = self.get_basic_type(value) + self.value = value + + self.element = self.value['element'] + self.eltype = self.value['type'] + self.ghost_type = self.value['ghost_type'] + + def to_string (self): + m = self.regex.search(self.typename) + return 'Element({0}, {1}, {2})'.format(self.element, self.eltype, self.ghost_type) + +#@register_pretty_printer +#class AkantuElementTypeMapArrayPrinter(std.StdMapPrinter): +# """Pretty printer for akantu::ElementTypeMapArray""" +# regex = re.compile('^akantu::ElementTypeMapArray<(.*), akantu::(.*)>$') +# name = 'akantu::ElementTypeMapArray' +# +# def __init__ (self, value): +# self.typename = AkantuPrinter.get_basic_type(value) +# self.value = value +# +# def to_string (self): +# m = self.regex.search(self.typename) +# return '{0}MapArray<{1}> with {2} elements and {3} ghost elements'.format(m.group(2), +# m.group(1), +# len (std.RbtreeIterator (self.value['data'])), +# len (std.RbtreeIterator (self.value['data']))) +# +# def children (self): +# yield ('elements:', self.value['data'].children()) +# yield ('ghost elements:', self.value['data'].children()) +# +# def display_hint (self): +# return 'map' +# +#@register_pretty_printer +#class AkantuElementTypeMapPrinter(std.StdMapPrinter): +# """Pretty printer for akantu::ElementTypeMap""" +# regex = re.compile('^akantu::ElementTypeMap<(.*), akantu::(.*)>$') +# name = 'akantu::ElementTypeMap' +# +# def __init__ (self, value): +# self.typename = AkantuPrinter.get_basic_type(value) +# self.value = value +# +# def to_string (self): +# m = self.regex.search(self.typename) +# return '%s<%s> with %d elements' % (m.group(2), m.group(1), +# len (std.RbtreeIterator (self.value['data']))) +# +# def display_hint (self): +# return 'map' +# + +def register_akantu_printers(obj): + "Register Akantu Pretty Printers." + + if __use_gdb_pp__: + gdb.printing.register_pretty_printer(obj, __akantu_pretty_printers__) + else: + if obj is None: + obj = gdb + obj.pretty_printers.append(__akantu_pretty_printers__) + + diff --git a/examples/io/dumper/CMakeLists.txt b/examples/io/dumper/CMakeLists.txt index 8a1b0d675..03d05c85b 100644 --- a/examples/io/dumper/CMakeLists.txt +++ b/examples/io/dumper/CMakeLists.txt @@ -1,58 +1,59 @@ #=============================================================================== # @file CMakeLists.txt # # @author Fabian Barras # # @date creation: Fri Sep 03 2010 # @date last modification: Wed Jan 20 2016 # # @brief CMakeLists for DumperIOHelper examples # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # # @section DESCRIPTION # #=============================================================================== add_mesh(swiss_train_mesh swiss_train.geo 2 1) add_library(locomotive_tools locomotive_tools.cc locomotive_tools.hh ) -target_include_directories(locomotive_tools PRIVATE ${AKANTU_INCLUDE_DIRS}) +package_get_include_dir(BOOST _inc_dir) +target_include_directories(locomotive_tools PRIVATE ${AKANTU_INCLUDE_DIRS} ${_inc_dir}) if(AKANTU_EXTRA_CXX_FLAGS) set_target_properties(locomotive_tools PROPERTIES COMPILE_FLAGS ${AKANTU_EXTRA_CXX_FLAGS}) endif() register_example(dumper_low_level SOURCES dumper_low_level.cc USE_PACKAGES IOHelper DEPENDS swiss_train_mesh locomotive_tools ) register_example(dumpable_interface SOURCES dumpable_interface.cc USE_PACKAGES IOHelper DEPENDS swiss_train_mesh locomotive_tools ) diff --git a/extra_packages/extra-materials b/extra_packages/extra-materials index dea972981..fde4bb4ac 160000 --- a/extra_packages/extra-materials +++ b/extra_packages/extra-materials @@ -1 +1 @@ -Subproject commit dea9729814e7967a4088ac100749be7f3e0ca6cd +Subproject commit fde4bb4acfd0071d250e615615c5554b2a3d103d diff --git a/extra_packages/parallel-cohesive-element b/extra_packages/parallel-cohesive-element index 4e4270f3c..81bcb4b82 160000 --- a/extra_packages/parallel-cohesive-element +++ b/extra_packages/parallel-cohesive-element @@ -1 +1 @@ -Subproject commit 4e4270f3c06f17adf40f0d6d27f9fcdff1ce5c03 +Subproject commit 81bcb4b82d2ff8fe294fa27fd6161fc26c372dfb diff --git a/extra_packages/phase-field b/extra_packages/phase-field index 0ec10337f..455aead38 160000 --- a/extra_packages/phase-field +++ b/extra_packages/phase-field @@ -1 +1 @@ -Subproject commit 0ec10337f210ea87aac26436b463e96c7cfd30c5 +Subproject commit 455aead384c4d806462518bbf270c564326b87ff diff --git a/packages/mumps.cmake b/packages/mumps.cmake index fb5f9d401..229d5ff40 100644 --- a/packages/mumps.cmake +++ b/packages/mumps.cmake @@ -1,100 +1,112 @@ #=============================================================================== # @file mumps.cmake # # @author Nicolas Richart # # @date creation: Mon Nov 21 2011 # @date last modification: Mon Jan 18 2016 # # @brief package description for mumps support # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== package_declare(Mumps EXTERNAL DESCRIPTION "Add Mumps support in akantu" SYSTEM ON third-party/cmake/mumps.cmake ) package_declare_sources(Mumps solver/solver_mumps.cc solver/solver_mumps.hh ) + +set(_mumps_float_type ${AKANTU_FLOAT_TYPE}) + +if(AKANTU_FLOAT_TYPE STREQUAL "float" OR + AKANTU_FLOAT_TYPE STREQUAL "double") + set(_mumps_components ${AKANTU_FLOAT_TYPE}) +else() + if(DEFINED AKANTU_FLOAT_TYPE) + message(FATAL_ERROR "MUMPS doea not support floating point type \"${AKANTU_FLOAT_TYPE}\"") + endif() +endif() + package_get_option_name(parallel _par_option) if(${_par_option}) - package_set_find_package_extra_options(Mumps ARGS COMPONENTS "parallel") + package_set_find_package_extra_options(Mumps ARGS COMPONENTS "parallel" ${_mumps_components}) package_add_third_party_script_variable(Mumps MUMPS_TYPE "par") package_set_package_system_dependency(Mumps deb libmumps) package_set_package_system_dependency(Mumps deb-src libmumps-dev) else() - package_set_find_package_extra_options(Mumps ARGS COMPONENTS "sequential") + package_set_find_package_extra_options(Mumps ARGS COMPONENTS "sequential" ${_mumps_components}) package_add_third_party_script_variable(Mumps MUMPS_TYPE "seq") package_set_package_system_dependency(Mumps deb libmumps-seq) package_set_package_system_dependency(Mumps deb-src libmumps-seq-dev) endif() package_use_system(Mumps _use_system) if(NOT _use_system) enable_language(Fortran) set(AKANTU_USE_MUMPS_VERSION "4.10.0" CACHE STRING "Default Mumps version to compile") mark_as_advanced(AKANTU_USE_MUMPS_VERSION) set_property(CACHE AKANTU_USE_MUMPS_VERSION PROPERTY STRINGS "4.9.2" "4.10.0" "5.0.0") package_get_option_name(MPI _mpi_option) if(${_mpi_option}) package_add_dependencies(Mumps ScaLAPACK MPI) endif() package_add_dependencies(Mumps Scotch BLAS) endif() package_declare_documentation(Mumps "This package enables the \\href{http://mumps.enseeiht.fr/}{MUMPS} parallel direct solver for sparce matrices." "This is necessary to solve static or implicit problems." "" "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:" "" "\\begin{command}" " > sudo apt-get install libmumps-seq-dev # for sequential" " > sudo apt-get install libmumps-dev # for parallel" "\\end{command}" "" "Under Mac OS X the installation requires the following steps:" "\\begin{command}" " > sudo port install mumps" "\\end{command}" "" "If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_MUMPS the make system of akantu can automatically compile MUMPS. For this you will have to download MUMPS from \\url{http://mumps.enseeiht.fr/} or \\url{http://graal.ens-lyon.fr/MUMPS} and place it in \\shellcode{/third-party}" ) package_declare_extra_files_to_package(MUMPS PROJECT third-party/MUMPS_4.10.0_make.inc.cmake third-party/MUMPS_5.0.0.patch third-party/MUMPS_4.10.0.patch third-party/MUMPS_4.9.2_make.inc.cmake third-party/cmake/mumps.cmake cmake/Modules/FindMumps.cmake ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d165d6806..e0c7475e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,170 +1,207 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Jun 14 2010 # @date last modification: Wed Jan 20 2016 # # @brief CMake file for the library # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== #=============================================================================== # Package Management #=============================================================================== package_get_all_source_files( AKANTU_LIBRARY_SRCS AKANTU_LIBRARY_PUBLIC_HDRS AKANTU_LIBRARY_PRIVATE_HDRS ) package_get_all_include_directories( AKANTU_LIBRARY_INCLUDE_DIRS ) package_get_all_external_informations( AKANTU_EXTERNAL_INCLUDE_DIR AKANTU_EXTERNAL_LIBRARIES ) package_get_all_compilation_flags(CXX _cxx_flags) set(AKANTU_EXTRA_CXX_FLAGS "${_cxx_flags}" CACHE STRING "Extra flags defined by loaded packages" FORCE) mark_as_advanced(AKANTU_EXTRA_CXX_FLAGS) #=========================================================================== # header for blas/lapack (any other fortran libraries) #=========================================================================== package_is_activated(BLAS _blas_activated) package_is_activated(LAPACK _lapack_activated) if(_blas_activated OR _lapack_activated) if(CMAKE_Fortran_COMPILER) # ugly hack set(CMAKE_Fortran_COMPILER_LOADED TRUE) endif() include(FortranCInterface) FortranCInterface_HEADER( - ${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh + "${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh" MACRO_NAMESPACE "AKA_FC_") mark_as_advanced(CDEFS) list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh) + "${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh") endif() #=========================================================================== # configurations #=========================================================================== package_get_all_material_includes(AKANTU_MATERIAL_INCLUDES) package_get_all_material_lists(AKANTU_MATERIAL_LISTS) configure_file(model/solid_mechanics/material_list.hh.in "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh" @ONLY) package_get_element_lists() configure_file(common/aka_element_classes_info.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" @ONLY) configure_file(common/aka_config.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY) list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh - ${CMAKE_CURRENT_BINARY_DIR}/material_list.hh) -list(APPEND AKANTU_LIBRARY_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) + "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" + "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" + "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh") +list(APPEND AKANTU_LIBRARY_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}") #=========================================================================== # header precompilation #=========================================================================== set(AKANTU_COMMON_HDR_TO_PRECOMPILE common/aka_vector.hh common/aka_math.hh common/aka_types.hh fem/element_class.hh ) set(AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/common/ ${CMAKE_CURRENT_BINARY_DIR}/fem/ ) set(AKANTU_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS} CACHE INTERNAL "Internal include directories to link with Akantu as a subproject") include_directories(${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR}) if(CMAKE_COMPILER_IS_GNUCXX) include(PCHgcc) foreach(_header ${AKANTU_COMMON_HDR_TO_PRECOMPILE}) add_pch_rule(${_header} AKANTU_LIBRARY_SRCS) endforeach() elseif(CMAKE_COMPILER_IS_GNUCXX) endif() +#=============================================================================== +# Debug infos +#=============================================================================== +set(AKANTU_GDB_DIR ${PROJECT_SOURCE_DIR}/cmake) +if(UNIX) + string(TOUPPER "${CMAKE_BUILD_TYPE}" _u_build_type) + if(_u_build_type STREQUAL "DEBUG" OR _u_build_type STREQUAL "RELWITHDEBINFO") + configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in + "${PROJECT_BINARY_DIR}/libakantu-gdb.py" + @ONLY) + configure_file(${PROJECT_SOURCE_DIR}/cmake/akantu-debug.cc.in + "${PROJECT_BINARY_DIR}/akantu-debug.cc" @ONLY) + + list(APPEND AKANTU_LIBRARY_SRCS ${PROJECT_BINARY_DIR}/akantu-debug.cc) + endif() +else() + find_program(GDB_EXECUTABLE gdb) + + if(GDB_EXECUTABLE) + execute_process(COMMAND + ${GDB_EXECUTABLE} --batch -x "${PROJECT_SOURCE_DIR}/cmake/gdb_python_path" + OUTPUT_VARIABLE AKANTU_PYTHON_GDB_DIR + ERROR_QUIET + RESULT_VARIABLE _res) + + if(_res EQUAL 0 AND UNIX) + set(GDB_USER_CONFIG $ENV{HOME}/.gdb/auto-load) + file(MAKE_DIRECTORY ${GDB_USER_CONFIG}) + + configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in + "${GDB_USER_CONFIG}/${CMAKE_SHARED_LIBRARY_PREFIX}akantu${CMAKE_SHARED_LIBRARY_SUFFIX}.${AKANTU_VERSION}-gdb.py" + @ONLY) + endif() + endif() +endif() + #=============================================================================== # Library generation #=============================================================================== add_library(akantu ${AKANTU_LIBRARY_SRCS}) # the repetition is ugly but works for static libraries target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES} ${AKANTU_EXTERNAL_LIBRARIES}) set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES} # this contains the version PUBLIC_HEADER "${AKANTU_LIBRARY_PUBLIC_HDRS}" COMPILE_FLAGS "${_cxx_flags}" LINK_INTERFACE_MULTIPLICITY 2) package_get_all_extra_dependencies(_extra_target_dependencies) if(_extra_target_dependencies) # This only adding todo: find a solution for when a dependency was add the is removed... add_dependencies(akantu ${_extra_target_dependencies}) endif() list(APPEND AKANTU_EXPORT_LIST akantu) # TODO separate public from private headers install(TARGETS akantu EXPORT ${AKANTU_TARGETS_EXPORT} LIBRARY DESTINATION lib COMPONENT lib ARCHIVE DESTINATION lib COMPONENT lib RUNTIME DESTINATION bin COMPONENT bin PUBLIC_HEADER DESTINATION include/akantu/ COMPONENT dev ) if("${AKANTU_TARGETS_EXPORT}" STREQUAL "AkantuLibraryDepends") install(EXPORT AkantuLibraryDepends DESTINATION lib/akantu COMPONENT dev) endif() #Export for build tree export(TARGETS ${AKANTU_EXPORT_LIST} FILE "${CMAKE_BINARY_DIR}/AkantuLibraryDepends.cmake") export(PACKAGE Akantu) # print out the list of materials generate_material_list() diff --git a/src/fe_engine/element_class.hh b/src/fe_engine/element_class.hh index 4910d16e9..5d9192541 100644 --- a/src/fe_engine/element_class.hh +++ b/src/fe_engine/element_class.hh @@ -1,396 +1,396 @@ /** * @file element_class.hh * * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Thu Jan 21 2016 * * @brief Declaration of the ElementClass main class and the * Integration and Interpolation elements * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_types.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_ELEMENT_CLASS_HH__ #define __AKANTU_ELEMENT_CLASS_HH__ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /// default element class structure template struct ElementClassProperty { static const GeometricalType geometrical_type = _gt_not_defined; static const InterpolationType interpolation_type = _itp_not_defined; static const ElementKind element_kind = _ek_regular; static const UInt spatial_dimension = 0; static const GaussIntergrationType gauss_integration_type = _git_not_defined; static const UInt minimal_integration_order = 0; }; /// Macro to generate the element class structures for different element types #define AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(elem_type, geom_type, \ interp_type, elem_kind, sp, \ gauss_int_type, min_int_order) \ template <> struct ElementClassProperty { \ static const GeometricalType geometrical_type = geom_type; \ static const InterpolationType interpolation_type = interp_type; \ static const ElementKind element_kind = elem_kind; \ static const UInt spatial_dimension = sp; \ static const GaussIntergrationType gauss_integration_type = \ gauss_int_type; \ static const UInt minimal_integration_order = min_int_order; \ } /* -------------------------------------------------------------------------- */ /* Geometry */ /* -------------------------------------------------------------------------- */ /// Default GeometricalShape structure template struct GeometricalShape { static const GeometricalShapeType shape = _gst_point; }; /// Templated GeometricalShape with function contains template struct GeometricalShapeContains { /// Check if the point (vector in 2 and 3D) at natural coordinate coor template static inline bool contains(const vector_type & coord); }; /// Macro to generate the GeometricalShape structures for different geometrical /// types #define AKANTU_DEFINE_SHAPE(geom_type, geom_shape) \ template <> struct GeometricalShape { \ static const GeometricalShapeType shape = geom_shape; \ } /* -------------------------------------------------------------------------- */ /// Templated GeometricalElement with function getInradius template ::shape> class GeometricalElement { public: /// compute the in-radius static inline Real getInradius(__attribute__((unused)) const Matrix & coord) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// true if the natural coordinates are in the element template static inline bool contains(const vector_type & coord); public: static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, spatial_dimension, UInt); static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerElement, nb_nodes_per_element, UInt); static AKANTU_GET_MACRO_NOT_CONST(NbFacetTypes, nb_facet_types, UInt); static inline UInt getNbFacetsPerElement(UInt t); static inline UInt getNbFacetsPerElement(); static inline const MatrixProxy getFacetLocalConnectivityPerElement(UInt t = 0); protected: /// Number of nodes per element static UInt nb_nodes_per_element; /// spatial dimension of the element static UInt spatial_dimension; /// number of different facet types static UInt nb_facet_types; /// number of facets for element static UInt nb_facets[]; /// storage of the facet local connectivity static UInt facet_connectivity_vect[]; /// local connectivity of facets static UInt * facet_connectivity[]; private: /// Type of the facet elements static UInt nb_nodes_per_facet[]; }; /* -------------------------------------------------------------------------- */ /* Interpolation */ /* -------------------------------------------------------------------------- */ /// default InterpolationPorperty structure template struct InterpolationPorperty { static const InterpolationKind kind = _itk_not_defined; static const UInt nb_nodes_per_element = 0; static const UInt natural_space_dimension = 0; }; /// Macro to generate the InterpolationPorperty structures for different /// interpolation types #define AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(itp_type, itp_kind, \ nb_nodes, ndim) \ template <> struct InterpolationPorperty { \ static const InterpolationKind kind = itp_kind; \ static const UInt nb_nodes_per_element = nb_nodes; \ static const UInt natural_space_dimension = ndim; \ } #include "interpolation_element_tmpl.hh" /* -------------------------------------------------------------------------- */ /// Generic (templated by the enum InterpolationType which specifies the order /// and the dimension of the interpolation) class handling the elemental /// interpolation template ::kind> class InterpolationElement { public: typedef InterpolationPorperty interpolation_property; /// compute the shape values for a given set of points in natural coordinates static inline void computeShapes(const Matrix & natural_coord, Matrix & N); /// compute the shape values for a given point in natural coordinates template static inline void computeShapes(__attribute__((unused)) const vector_type & natural_coord, __attribute__((unused)) vector_type & N) { AKANTU_DEBUG_TO_IMPLEMENT(); } /** * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of * shape functions along with variation of natural coordinates on a given set * of points in natural coordinates */ static inline void computeDNDS(const Matrix & natural_coord, Tensor3 & dnds); /** * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of * shape functions along with * variation of natural coordinates on a given point in natural * coordinates */ template static inline void computeDNDS(__attribute__((unused)) const vector_type & natural_coord, __attribute__((unused)) matrix_type & dnds) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute jacobian (or integration variable change factor) for a given point /// in the case of spatial_dimension != natural_space_dimension static inline void computeSpecialJacobian(__attribute__((unused)) const Matrix & J, __attribute__((unused)) Real & jacobians) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// interpolate a field given (arbitrary) natural coordinates static inline void interpolateOnNaturalCoordinates(const Vector & natural_coords, const Matrix & nodal_values, Vector & interpolated); /// interpolate a field given the shape functions on the interpolation point static inline void interpolate(const Matrix & nodal_values, const Vector & shapes, Vector & interpolated); /// interpolate a field given the shape functions on the interpolations points static inline void interpolate(const Matrix & nodal_values, const Matrix & shapes, Matrix & interpolated); /// compute the gradient of a given field on the given natural coordinates static inline void gradientOnNaturalCoordinates(const Vector & natural_coords, const Matrix & f, Matrix & gradient); public: static AKANTU_GET_MACRO_NOT_CONST( ShapeSize, InterpolationPorperty::nb_nodes_per_element, UInt); static AKANTU_GET_MACRO_NOT_CONST( ShapeDerivativesSize, (InterpolationPorperty::nb_nodes_per_element * InterpolationPorperty::natural_space_dimension), UInt); static AKANTU_GET_MACRO_NOT_CONST( NaturalSpaceDimension, InterpolationPorperty::natural_space_dimension, UInt); static AKANTU_GET_MACRO_NOT_CONST( NbNodesPerInterpolationElement, InterpolationPorperty::nb_nodes_per_element, UInt); }; /* -------------------------------------------------------------------------- */ /* Integration */ /* -------------------------------------------------------------------------- */ template struct GaussIntegrationTypeData { /// quadrature points in natural coordinates static Real quad_positions[]; /// weights for the Gauss integration static Real quad_weights[]; /// Number of quadrature points per element static UInt nb_quadrature_points; }; template ::minimal_integration_order> class GaussIntegrationElement { public: static UInt getNbQuadraturePoints(); static const Matrix getQuadraturePoints(); static const Vector getWeights(); }; /* -------------------------------------------------------------------------- */ /* ElementClass */ /* -------------------------------------------------------------------------- */ template ::element_kind> class ElementClass : public GeometricalElement< ElementClassProperty::geometrical_type>, public InterpolationElement< ElementClassProperty::interpolation_type> { protected: typedef GeometricalElement< ElementClassProperty::geometrical_type> geometrical_element; typedef InterpolationElement::interpolation_type> interpolation_element; typedef ElementClassProperty element_property; typedef typename interpolation_element::interpolation_property interpolation_property; public: /** * compute @f$ J = \frac{\partial x_j}{\partial s_i} @f$ the variation of real * coordinates along with variation of natural coordinates on a given point in * natural coordinates */ static inline void computeJMat(const Matrix & dnds, const Matrix & node_coords, Matrix & J); /** * compute the Jacobian matrix by computing the variation of real coordinates * along with variation of natural coordinates on a given set of points in * natural coordinates */ static inline void computeJMat(const Tensor3 & dnds, const Matrix & node_coords, Tensor3 & J); /// compute the jacobians of a serie of natural coordinates static inline void computeJacobian(const Matrix & natural_coords, const Matrix & node_coords, Vector & jacobians); /// compute jacobian (or integration variable change factor) for a set of /// points static inline void computeJacobian(const Tensor3 & J, Vector & jacobians); /// compute jacobian (or integration variable change factor) for a given point static inline void computeJacobian(const Matrix & J, Real & jacobians); /// compute shape derivatives (input is dxds) for a set of points static inline void computeShapeDerivatives(const Tensor3 & J, const Tensor3 & dnds, Tensor3 & shape_deriv); /// compute shape derivatives (input is dxds) for a given point static inline void computeShapeDerivatives(const Matrix & J, const Matrix & dnds, Matrix & shape_deriv); /// compute the normal of a surface defined by the function f static inline void computeNormalsOnNaturalCoordinates(const Matrix & coord, Matrix & f, Matrix & normals); /// get natural coordinates from real coordinates static inline void inverseMap(const Vector & real_coords, const Matrix & node_coords, Vector & natural_coords, Real tolerance = 1e-8); /// get natural coordinates from real coordinates static inline void inverseMap(const Matrix & real_coords, const Matrix & node_coords, Matrix & natural_coords, Real tolerance = 1e-8); public: static AKANTU_GET_MACRO_NOT_CONST(Kind, element_kind, ElementKind); static AKANTU_GET_MACRO_NOT_CONST( SpatialDimension, ElementClassProperty::spatial_dimension, UInt); static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, p1_type, const ElementType &); static const ElementType & getFacetType(UInt t = 0) { return facet_type[t]; } static ElementType * getFacetTypeInternal() { return facet_type; } protected: /// Type of the facet elements static ElementType facet_type[]; /// type of element P1 associated static ElementType p1_type; }; /* -------------------------------------------------------------------------- */ #include "element_class_tmpl.hh" /* -------------------------------------------------------------------------- */ -#include "element_classes/element_class_point_1_inline_impl.cc" -#include "element_classes/element_class_segment_2_inline_impl.cc" -#include "element_classes/element_class_segment_3_inline_impl.cc" -#include "element_classes/element_class_triangle_3_inline_impl.cc" -#include "element_classes/element_class_triangle_6_inline_impl.cc" -#include "element_classes/element_class_tetrahedron_4_inline_impl.cc" -#include "element_classes/element_class_tetrahedron_10_inline_impl.cc" -#include "element_classes/element_class_quadrangle_4_inline_impl.cc" -#include "element_classes/element_class_quadrangle_8_inline_impl.cc" -#include "element_classes/element_class_hexahedron_8_inline_impl.cc" -#include "element_classes/element_class_hexahedron_20_inline_impl.cc" -#include "element_classes/element_class_pentahedron_6_inline_impl.cc" -#include "element_classes/element_class_pentahedron_15_inline_impl.cc" +#include "element_class_point_1_inline_impl.cc" +#include "element_class_segment_2_inline_impl.cc" +#include "element_class_segment_3_inline_impl.cc" +#include "element_class_triangle_3_inline_impl.cc" +#include "element_class_triangle_6_inline_impl.cc" +#include "element_class_tetrahedron_4_inline_impl.cc" +#include "element_class_tetrahedron_10_inline_impl.cc" +#include "element_class_quadrangle_4_inline_impl.cc" +#include "element_class_quadrangle_8_inline_impl.cc" +#include "element_class_hexahedron_8_inline_impl.cc" +#include "element_class_hexahedron_20_inline_impl.cc" +#include "element_class_pentahedron_6_inline_impl.cc" +#include "element_class_pentahedron_15_inline_impl.cc" __END_AKANTU__ #if defined(AKANTU_STRUCTURAL_MECHANICS) #include "element_class_structural.hh" #endif #if defined(AKANTU_IGFEM) #include "element_class_igfem.hh" #endif #endif /* __AKANTU_ELEMENT_CLASS_HH__ */ diff --git a/src/geometry/mesh_abstract_intersector.hh b/src/geometry/mesh_abstract_intersector.hh index ea54bba64..b69beb764 100644 --- a/src/geometry/mesh_abstract_intersector.hh +++ b/src/geometry/mesh_abstract_intersector.hh @@ -1,108 +1,108 @@ /** * @file mesh_abstract_intersector.hh * * @author Lucas Frerot * @author Clement Roux * @author Marco Vocialta * * @date creation: Wed Apr 29 2015 * @date last modification: Thu Jan 14 2016 * * @brief Abstract class for intersection computations * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__ #define __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__ #include "aka_common.hh" #include "mesh_geom_abstract.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /** * @brief Class used to perform intersections on a mesh and construct output data */ template class MeshAbstractIntersector : public MeshGeomAbstract { public: /// Construct from mesh explicit MeshAbstractIntersector(Mesh & mesh); /// Destructor virtual ~MeshAbstractIntersector(); public: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the new_node_per_elem array AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array &); /// get the intersection_points array AKANTU_GET_MACRO(IntersectionPoints, intersection_points, const Array *); /// get the nb_seg_by_el UInt - AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, const UInt); + AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, UInt); /** * @brief Compute the intersection with a query object * * This function needs to be implemented for every subclass. It computes the intersections * with the tree of primitives and creates the data for the user. * * @param query the CGAL primitive of the query object */ virtual void computeIntersectionQuery(const Query & query) = 0; /// Compute intersection points between the mesh primitives (segments) and a query (surface in 3D or a curve in 2D), double intersection points for the same primitives are not considered. A maximum intersection node per element is set : 2 in 2D and 4 in 3D virtual void computeMeshQueryIntersectionPoint(const Query & query, UInt nb_old_nodes) = 0; /// Compute intersection between the mesh and a list of queries virtual void computeIntersectionQueryList(const std::list & query_list); /// Compute intersection points between the mesh and a list of queries virtual void computeMeshQueryListIntersectionPoint(const std::list & query_list, UInt nb_old_nodes); /// Compute whatever result is needed from the user (should be move to the appropriate specific classe for genericity) virtual void buildResultFromQueryList(const std::list & query_list) = 0; protected: /// new node per element (column 0: number of new nodes, then odd is the intersection node number and even the ID of the intersected segment) Array * new_node_per_elem; /// intersection output: new intersection points (computeMeshQueryListIntersectionPoint) Array * intersection_points; /// number of segment in a considered element of the templated type of element specialized intersector const UInt nb_seg_by_el; }; __END_AKANTU__ #include "mesh_abstract_intersector_tmpl.hh" #endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__ diff --git a/src/io/dumper/dumper_iohelper.cc b/src/io/dumper/dumper_iohelper.cc index a4f4a0a0e..542e7f91e 100644 --- a/src/io/dumper/dumper_iohelper.cc +++ b/src/io/dumper/dumper_iohelper.cc @@ -1,300 +1,302 @@ /** * @file dumper_iohelper.cc * * @author Guillaume Anciaux * @author Dana Christen * @author David Simon Kammer * @author Nicolas Richart * * @date creation: Fri Oct 26 2012 * @date last modification: Thu Sep 17 2015 * * @brief implementation of DumperIOHelper * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include "dumper_iohelper.hh" #include "dumper_elemental_field.hh" #include "dumper_nodal_field.hh" #include "dumper_filtered_connectivity.hh" #include "dumper_variable.hh" #include "mesh.hh" #if defined(AKANTU_IGFEM) #include "dumper_igfem_connectivity.hh" #endif /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ DumperIOHelper::DumperIOHelper() : count(0), time_activated(false) {} /* -------------------------------------------------------------------------- */ DumperIOHelper::~DumperIOHelper() { for (Fields::iterator it = fields.begin(); it != fields.end(); ++it) { delete it->second; } delete dumper; } /* -------------------------------------------------------------------------- */ void DumperIOHelper::setParallelContext(bool is_parallel) { UInt whoami = StaticCommunicator::getStaticCommunicator().whoAmI(); UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc(); if(is_parallel) dumper->setParallelContext(whoami, nb_proc); else dumper->setParallelContext(0, 1); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::setDirectory(const std::string & directory) { this->directory = directory; dumper->setPrefix(directory); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::setBaseName(const std::string & basename) { filename = basename; } /* -------------------------------------------------------------------------- */ void DumperIOHelper::setTimeStep(Real time_step) { if(!time_activated) this->dumper->activateTimeDescFiles(time_step); else this->dumper->setTimeStep(time_step); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::dump() { try { dumper->dump(filename, count); } catch (iohelper::IOHelperException & e) { AKANTU_DEBUG_ERROR("I was not able to dump your data with a Dumper: " << e.what()); } ++count; } /* -------------------------------------------------------------------------- */ void DumperIOHelper::dump(UInt step) { this->count = step; this->dump(); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::dump(Real current_time, UInt step) { this->dumper->setCurrentTime(current_time); this->dump(step); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::registerMesh(const Mesh & mesh, UInt spatial_dimension, const GhostType & ghost_type, const ElementKind & element_kind) { #if defined(AKANTU_IGFEM) if (element_kind == _ek_igfem) { registerField("connectivities", new dumper::IGFEMConnectivityField(mesh.getConnectivities(), spatial_dimension, ghost_type)); } else #endif registerField("connectivities", new dumper::ElementalField(mesh.getConnectivities(), spatial_dimension, ghost_type, element_kind)); registerField("positions", new dumper::NodalField(mesh.getNodes())); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::registerFilteredMesh(const Mesh & mesh, const ElementTypeMapArray & elements_filter, const Array & nodes_filter, UInt spatial_dimension, const GhostType & ghost_type, const ElementKind & element_kind) { ElementTypeMapArrayFilter * f_connectivities = new ElementTypeMapArrayFilter(mesh.getConnectivities(), elements_filter); this->registerField("connectivities", new dumper::FilteredConnectivityField(*f_connectivities, nodes_filter, spatial_dimension, ghost_type, element_kind)); this->registerField("positions",new dumper::NodalField( mesh.getNodes(), 0, 0, &nodes_filter)); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::registerField(const std::string & field_id, dumper::Field * field) { Fields::iterator it = fields.find(field_id); if(it != fields.end()) { AKANTU_DEBUG_WARNING("The field " << field_id << " is already registered in this Dumper. Field ignored."); return; } fields[field_id] = field; field->registerToDumper(field_id, *dumper); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::unRegisterField(const std::string & field_id) { Fields::iterator it = fields.find(field_id); if(it == fields.end()) { AKANTU_DEBUG_WARNING("The field " << field_id << " is not registered in this Dumper. Nothing to do."); return; } delete it->second; fields.erase(it); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::registerVariable(const std::string & variable_id, dumper::VariableBase * variable) { Variables::iterator it = variables.find(variable_id); if(it != variables.end()) { AKANTU_DEBUG_WARNING("The Variable " << variable_id << " is already registered in this Dumper. Variable ignored."); return; } variables[variable_id] = variable; variable->registerToDumper(variable_id, *dumper); } /* -------------------------------------------------------------------------- */ void DumperIOHelper::unRegisterVariable(const std::string & variable_id) { Variables::iterator it = variables.find(variable_id); if(it == variables.end()) { AKANTU_DEBUG_WARNING("The variable " << variable_id << " is not registered in this Dumper. Nothing to do."); return; } delete it->second; variables.erase(it); } /* -------------------------------------------------------------------------- */ template iohelper::ElemType getIOHelperType() { AKANTU_DEBUG_TO_IMPLEMENT(); return iohelper::MAX_ELEM_TYPE; } +template <> +iohelper::ElemType getIOHelperType<_point_1>() { return iohelper::POINT_SET; } template <> iohelper::ElemType getIOHelperType<_segment_2>() { return iohelper::LINE1; } template <> iohelper::ElemType getIOHelperType<_segment_3>() { return iohelper::LINE2; } template <> iohelper::ElemType getIOHelperType<_triangle_3>() { return iohelper::TRIANGLE1; } template <> iohelper::ElemType getIOHelperType<_triangle_6>() { return iohelper::TRIANGLE2; } template <> iohelper::ElemType getIOHelperType<_quadrangle_4>() { return iohelper::QUAD1; } template <> iohelper::ElemType getIOHelperType<_quadrangle_8>() { return iohelper::QUAD2; } template <> iohelper::ElemType getIOHelperType<_tetrahedron_4>() { return iohelper::TETRA1; } template <> iohelper::ElemType getIOHelperType<_tetrahedron_10>() { return iohelper::TETRA2; } template <> iohelper::ElemType getIOHelperType<_hexahedron_8>() { return iohelper::HEX1; } template <> iohelper::ElemType getIOHelperType<_hexahedron_20>() { return iohelper::HEX2; } template <> iohelper::ElemType getIOHelperType<_pentahedron_6>() { return iohelper::PRISM1; } template <> iohelper::ElemType getIOHelperType<_pentahedron_15>() { return iohelper::PRISM2; } #if defined(AKANTU_COHESIVE_ELEMENT) template <> iohelper::ElemType getIOHelperType<_cohesive_2d_4>() { return iohelper::COH2D4; } template <> iohelper::ElemType getIOHelperType<_cohesive_2d_6>() { return iohelper::COH2D6; } template <> iohelper::ElemType getIOHelperType<_cohesive_3d_6>() { return iohelper::COH3D6; } template <> iohelper::ElemType getIOHelperType<_cohesive_3d_12>() { return iohelper::COH3D12; } template <> iohelper::ElemType getIOHelperType<_cohesive_3d_8>() { return iohelper::COH3D8; } //template <> //iohelper::ElemType getIOHelperType<_cohesive_3d_16>() { return iohelper::COH3D16; } #endif #if defined(AKANTU_STRUCTURAL_MECHANICS) template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_2>() { return iohelper::BEAM2; } template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_3>() { return iohelper::BEAM3; } #endif /* -------------------------------------------------------------------------- */ UInt getIOHelperType(ElementType type) { UInt ioh_type = iohelper::MAX_ELEM_TYPE; #define GET_IOHELPER_TYPE(type) \ ioh_type = getIOHelperType(); AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_IOHELPER_TYPE); #undef GET_IOHELPER_TYPE return ioh_type; } /* -------------------------------------------------------------------------- */ __END_AKANTU__ namespace iohelper { template<> DataType getDataType() { return _int; } } diff --git a/src/io/mesh_io/mesh_io_abaqus.cc b/src/io/mesh_io/mesh_io_abaqus.cc index 8c08680aa..f5b8105d8 100644 --- a/src/io/mesh_io/mesh_io_abaqus.cc +++ b/src/io/mesh_io/mesh_io_abaqus.cc @@ -1,542 +1,483 @@ /** * @file mesh_io_abaqus.cc * * @author Daniel Pino Muñoz * @author Nicolas Richart * * @date creation: Fri Jan 04 2013 * @date last modification: Fri Dec 11 2015 * * @brief read a mesh from an abaqus input file * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ // std library header files #include // akantu header files #include "mesh_io_abaqus.hh" #include "mesh.hh" #include "mesh_utils.hh" #include "element_group.hh" #include "node_group.hh" -/* -------------------------------------------------------------------------- */ -//#define BOOST_SPIRIT_USE_PHOENIX_V3 1 -//#define BOOST_RESULT_OF_USE_TR1 +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif (defined(__GNUC__) || defined(__GNUG__)) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + +/* -------------------------------------------------------------------------- */ #include #include #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ MeshIOAbaqus::MeshIOAbaqus() {} /* -------------------------------------------------------------------------- */ MeshIOAbaqus::~MeshIOAbaqus() {} /* -------------------------------------------------------------------------- */ namespace spirit = boost::spirit; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace lbs = boost::spirit::qi::labels; namespace phx = boost::phoenix; -namespace mesh_io_abaqus_lazy_eval { -struct mesh_abaqus_error_handler_ { - template struct result { typedef void type; }; - - template - void operator()(qi::info const & what, Iterator err_pos, - Iterator last) const { - AKANTU_EXCEPTION( - "Error! Expecting " - << what // what failed? - << " here: \"" - << std::string(err_pos, last) // iterators to error-pos, end - << "\""); - } -}; - -struct lazy_element_read_ { - template - struct result { - typedef void type; - }; - - template - void operator()(Mesh & mesh, const ET & type, const ID & id, const V & conn, - const NodeMap & nodes_mapping, - ElemMap & elements_mapping) const { - Vector tmp_conn(Mesh::getNbNodesPerElement(type)); - - AKANTU_DEBUG_ASSERT(conn.size() == tmp_conn.size(), - "The nodes in the Abaqus file have too many coordinates" - << " for the mesh you try to fill."); - - mesh.addConnectivityType(type); - Array & connectivity = mesh.getConnectivity(type); - - UInt i = 0; - for (typename V::const_iterator it = conn.begin(); it != conn.end(); ++it) { - typename NodeMap::const_iterator nit = nodes_mapping.find(*it); - AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(), - "There is an unknown node in the connectivity."); - tmp_conn[i++] = nit->second; - } - Element el(type, connectivity.getSize()); - elements_mapping[id] = el; - connectivity.push_back(tmp_conn); - } -}; +/* -------------------------------------------------------------------------- */ +void element_read(Mesh & mesh, const ElementType & type, UInt id, const std::vector & conn, + const std::map & nodes_mapping, + std::map & elements_mapping) { + Vector tmp_conn(Mesh::getNbNodesPerElement(type)); -struct lazy_node_read_ { - template struct result { - typedef void type; - }; - - template - void operator()(Mesh & mesh, const ID & id, const V & pos, - Map & nodes_mapping) const { - Vector tmp_pos(mesh.getSpatialDimension()); - UInt i = 0; - for (typename V::const_iterator it = pos.begin(); - it != pos.end() || i < mesh.getSpatialDimension(); ++it) - tmp_pos[i++] = *it; - - nodes_mapping[id] = mesh.getNbNodes(); - mesh.getNodes().push_back(tmp_pos); - } -}; + AKANTU_DEBUG_ASSERT(conn.size() == tmp_conn.size(), + "The nodes in the Abaqus file have too many coordinates" + << " for the mesh you try to fill."); -/* ------------------------------------------------------------------------ */ -struct lazy_element_group_create_ { - template struct result { typedef ElementGroup & type; }; + mesh.addConnectivityType(type); + Array & connectivity = mesh.getConnectivity(type); - template - ElementGroup & operator()(Mesh & mesh, const S & name) const { - typename Mesh::element_group_iterator eg_it = mesh.element_group_find(name); - if (eg_it != mesh.element_group_end()) { - return *eg_it->second; - } else { - return mesh.createElementGroup(name, _all_dimensions); - } + UInt i = 0; + for (std::vector::const_iterator it = conn.begin(); it != conn.end(); ++it) { + std::map::const_iterator nit = nodes_mapping.find(*it); + AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(), + "There is an unknown node in the connectivity."); + tmp_conn[i++] = nit->second; } -}; + Element el(type, connectivity.getSize()); + elements_mapping[id] = el; + connectivity.push_back(tmp_conn); +} -struct lazy_add_element_to_group_ { - template struct result { typedef void type; }; - template - void operator()(EG * el_grp, const ID & element, - const Map & elements_mapping) const { - typename Map::const_iterator eit = elements_mapping.find(element); - AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(), - "There is an unknown element (" - << element << ") in the in the ELSET " - << el_grp->getName() << "."); +void node_read(Mesh & mesh, UInt id, const std::vector & pos, + std::map & nodes_mapping) { + Vector tmp_pos(mesh.getSpatialDimension()); + UInt i = 0; + for (std::vector::const_iterator it = pos.begin(); + it != pos.end() || i < mesh.getSpatialDimension(); ++it) + tmp_pos[i++] = *it; - el_grp->add(eit->second, true, false); - } -}; - -/* ------------------------------------------------------------------------ */ -struct lazy_node_group_create_ { - template struct result { typedef NodeGroup & type; }; - - template - NodeGroup & operator()(Mesh & mesh, const S & name) const { - typename Mesh::node_group_iterator ng_it = mesh.node_group_find(name); - if (ng_it != mesh.node_group_end()) { - return *ng_it->second; - } else { - return mesh.createNodeGroup(name, mesh.getSpatialDimension()); - } - } -}; + nodes_mapping[id] = mesh.getNbNodes(); + mesh.getNodes().push_back(tmp_pos); +} -struct lazy_add_node_to_group_ { - template struct result { typedef void type; }; - template - void operator()(NG * node_grp, const ID & node, - const Map & nodes_mapping) const { - typename Map::const_iterator nit = nodes_mapping.find(node); +/* ------------------------------------------------------------------------ */ +void add_element_to_group(ElementGroup * el_grp, UInt element, + const std::map & elements_mapping) { + std::map::const_iterator eit = elements_mapping.find(element); + AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(), + "There is an unknown element (" + << element << ") in the in the ELSET " + << el_grp->getName() << "."); + + el_grp->add(eit->second, true, false); +} - AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(), - "There is an unknown node in the in the NSET " - << node_grp->getName() << "."); +ElementGroup * element_group_create(Mesh & mesh, const ID & name) { + Mesh::element_group_iterator eg_it = mesh.element_group_find(name); + if (eg_it != mesh.element_group_end()) { + return eg_it->second; + } else { + return &mesh.createElementGroup(name, _all_dimensions); + } +} - node_grp->add(nit->second, false); +NodeGroup * node_group_create(Mesh & mesh, const ID & name) { + Mesh::node_group_iterator ng_it = mesh.node_group_find(name); + if (ng_it != mesh.node_group_end()) { + return ng_it->second; + } else { + return &mesh.createNodeGroup(name, mesh.getSpatialDimension()); } -}; +} -struct lazy_optimize_group_ { - template struct result { typedef void type; }; - template void operator()(G * grp) const { grp->optimize(); } -}; +void add_node_to_group(NodeGroup * node_grp, UInt node, + const std::map & nodes_mapping) { + std::map::const_iterator nit = nodes_mapping.find(node); + + AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(), + "There is an unknown node in the in the NSET " + << node_grp->getName() << "."); + + node_grp->add(nit->second, false); } +void optimize_group(NodeGroup * grp) { grp->optimize(); } +void optimize_element_group(ElementGroup * grp) { grp->optimize(); } + /* -------------------------------------------------------------------------- */ template struct AbaqusSkipper : qi::grammar { AbaqusSkipper() : AbaqusSkipper::base_type(skip, "abaqus_skipper") { /* clang-format off */ skip = (ascii::space - spirit::eol) | "**" >> *(qi::char_ - spirit::eol) >> spirit::eol ; /* clang-format on */ } qi::rule skip; }; /* -------------------------------------------------------------------------- */ template > struct AbaqusMeshGrammar : qi::grammar { public: AbaqusMeshGrammar(Mesh & mesh) : AbaqusMeshGrammar::base_type(start, "abaqus_mesh_reader"), mesh(mesh) { - phx::function const - error_handler = mesh_io_abaqus_lazy_eval::mesh_abaqus_error_handler_(); - phx::function - lazy_element_read; - phx::function lazy_node_read; - phx::function - lazy_element_group_create; - phx::function - lazy_add_element_to_group; - phx::function - lazy_node_group_create; - phx::function - lazy_add_node_to_group; - phx::function - lazy_optimize_group; /* clang-format off */ start = *( (qi::char_('*') > ( (qi::no_case[ qi::lit("node output") ] > any_section) | (qi::no_case[ qi::lit("element output") ] > any_section) | (qi::no_case[ qi::lit("node") ] > nodes) | (qi::no_case[ qi::lit("element") ] > elements) | (qi::no_case[ qi::lit("heading") ] > header) | (qi::no_case[ qi::lit("elset") ] > elements_set) | (qi::no_case[ qi::lit("nset") ] > nodes_set) | (qi::no_case[ qi::lit("material") ] > material) | (keyword > any_section) ) ) | spirit::eol ) ; header = spirit::eol > *any_line ; nodes = *(qi::char_(',') >> option) >> spirit::eol >> *( (qi::int_ - > node_position) [ lazy_node_read(phx::ref(mesh), - lbs::_1, - lbs::_2, - phx::ref(abaqus_nodes_to_akantu)) ] + > node_position) [ phx::bind(&node_read, + phx::ref(mesh), + lbs::_1, + lbs::_2, + phx::ref(abaqus_nodes_to_akantu)) ] >> spirit::eol ) ; elements = ( ( qi::char_(',') >> qi::no_case[qi::lit("type")] >> '=' >> abaqus_element_type [ lbs::_a = lbs::_1 ] ) ^ *(qi::char_(',') >> option) ) >> spirit::eol >> *( (qi::int_ - > connectivity) [ lazy_element_read(phx::ref(mesh), - lbs::_a, - lbs::_1, - lbs::_2, - phx::cref(abaqus_nodes_to_akantu), - phx::ref(abaqus_elements_to_akantu)) ] + > connectivity) [ phx::bind(&element_read, + phx::ref(mesh), + lbs::_a, + lbs::_1, + lbs::_2, + phx::cref(abaqus_nodes_to_akantu), + phx::ref(abaqus_elements_to_akantu)) ] >> spirit::eol ) ; elements_set = ( ( ( qi::char_(',') >> qi::no_case[ qi::lit("elset") ] >> '=' - >> value [ lbs::_a = &lazy_element_group_create(phx::ref(mesh), lbs::_1) ] + >> value [ lbs::_a = phx::bind(&element_group_create, + phx::ref(mesh), + lbs::_1) ] ) ^ *(qi::char_(',') >> option) ) >> spirit::eol >> qi::skip (qi::char_(',') | qi::space) - [ +(qi::int_ [ lazy_add_element_to_group(lbs::_a, - lbs::_1, - phx::cref(abaqus_elements_to_akantu) - ) + [ +(qi::int_ [ phx::bind(&add_element_to_group, + lbs::_a, + lbs::_1, + phx::cref(abaqus_elements_to_akantu) + ) ] ) ] - ) [ lazy_optimize_group(lbs::_a) ] + ) [ phx::bind(&optimize_element_group, lbs::_a) ] ; nodes_set = ( ( ( qi::char_(',') >> qi::no_case[ qi::lit("nset") ] >> '=' - >> value [ lbs::_a = &lazy_node_group_create(phx::ref(mesh), lbs::_1) ] + >> value [ lbs::_a = phx::bind(&node_group_create, phx::ref(mesh), lbs::_1) ] ) ^ *(qi::char_(',') >> option) ) >> spirit::eol >> qi::skip (qi::char_(',') | qi::space) - [ +(qi::int_ [ lazy_add_node_to_group(lbs::_a, - lbs::_1, - phx::cref(abaqus_nodes_to_akantu) - ) + [ +(qi::int_ [ phx::bind(&add_node_to_group, + lbs::_a, + lbs::_1, + phx::cref(abaqus_nodes_to_akantu) + ) ] ) ] - ) [ lazy_optimize_group(lbs::_a) ] + ) [ phx::bind(&optimize_group, lbs::_a) ] ; material = ( ( qi::char_(',') >> qi::no_case[ qi::lit("name") ] >> '=' >> value [ phx::push_back(phx::ref(material_names), lbs::_1) ] ) ^ *(qi::char_(',') >> option) ) >> spirit::eol; ; node_position = +(qi::char_(',') > real [ phx::push_back(lbs::_val, lbs::_1) ]) ; connectivity = +(qi::char_(',') > qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ]) ; any_section = *(qi::char_(',') >> option) > spirit::eol > *any_line ; any_line = *(qi::char_ - spirit::eol - qi::char_('*')) >> spirit::eol ; keyword = qi::lexeme[ +(qi::char_ - (qi::char_('*') | spirit::eol)) ] ; option = key > -( '=' >> value ); key = qi::char_("a-zA-Z_") >> *(qi::char_("a-zA-Z_0-9") | qi::char_('-')) ; value = key.alias() ; BOOST_SPIRIT_DEBUG_NODE(start); abaqus_element_type.add #if defined(AKANTU_STRUCTURAL_MECHANICS) ("BE21" , _bernoulli_beam_2) ("BE31" , _bernoulli_beam_3) #endif ("T3D2" , _segment_2) // Gmsh generates this elements ("T3D3" , _segment_3) // Gmsh generates this elements ("CPE3" , _triangle_3) ("CPS3" , _triangle_3) ("DC2D3" , _triangle_3) ("CPE6" , _triangle_6) ("CPS6" , _triangle_6) ("DC2D6" , _triangle_6) ("CPE4" , _quadrangle_4) ("CPS4" , _quadrangle_4) ("DC2D4" , _quadrangle_4) ("CPE8" , _quadrangle_8) ("CPS8" , _quadrangle_8) ("DC2D8" , _quadrangle_8) ("C3D4" , _tetrahedron_4) ("DC3D4" , _tetrahedron_4) ("C3D8" , _hexahedron_8) ("C3D8R" , _hexahedron_8) ("DC3D8" , _hexahedron_8) ("C3D10" , _tetrahedron_10) ("DC3D10", _tetrahedron_10); +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_2)); - +#endif + start .name("abaqus-start-rule"); connectivity .name("abaqus-connectivity"); node_position .name("abaqus-nodes-position"); nodes .name("abaqus-nodes"); any_section .name("abaqus-any_section"); header .name("abaqus-header"); material .name("abaqus-material"); elements .name("abaqus-elements"); elements_set .name("abaqus-elements-set"); nodes_set .name("abaqus-nodes-set"); key .name("abaqus-key"); value .name("abaqus-value"); option .name("abaqus-option"); keyword .name("abaqus-keyword"); any_line .name("abaqus-any-line"); abaqus_element_type.name("abaqus-element-type"); /* clang-format on */ } public: AKANTU_GET_MACRO(MaterialNames, material_names, const std::vector &); /* ------------------------------------------------------------------------ */ /* Rules */ /* ------------------------------------------------------------------------ */ private: qi::rule start; qi::rule(), Skipper> connectivity; qi::rule(), Skipper> node_position; qi::rule nodes, any_section, header, material; qi::rule, Skipper> elements; qi::rule, Skipper> elements_set; qi::rule, Skipper> nodes_set; qi::rule key, value, option, keyword, any_line; qi::real_parser > real; qi::symbols abaqus_element_type; /* ------------------------------------------------------------------------ */ /* Mambers */ /* ------------------------------------------------------------------------ */ private: /// reference to the mesh to read Mesh & mesh; /// correspondance between the numbering of nodes in the abaqus file and in /// the akantu mesh std::map abaqus_nodes_to_akantu; /// correspondance between the element number in the abaqus file and the /// Element in the akantu mesh std::map abaqus_elements_to_akantu; /// list of the material names std::vector material_names; }; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ void MeshIOAbaqus::read(const std::string & filename, Mesh & mesh) { namespace spirit = boost::spirit; namespace qi = boost::spirit::qi; namespace lbs = boost::spirit::qi::labels; namespace ascii = boost::spirit::ascii; namespace phx = boost::phoenix; std::ifstream infile; infile.open(filename.c_str()); if (!infile.good()) { AKANTU_DEBUG_ERROR("Cannot open file " << filename); } std::string storage; // We will read the contents here. infile.unsetf(std::ios::skipws); // No white space skipping! std::copy(std::istream_iterator(infile), std::istream_iterator(), std::back_inserter(storage)); typedef std::string::const_iterator iterator_t; typedef AbaqusSkipper skipper; typedef AbaqusMeshGrammar grammar; grammar g(mesh); skipper ws; iterator_t iter = storage.begin(); iterator_t end = storage.end(); qi::phrase_parse(iter, end, g, ws); std::vector::const_iterator mnit = g.getMaterialNames().begin(); std::vector::const_iterator mnend = g.getMaterialNames().end(); MeshAccessor mesh_accessor(mesh); for (; mnit != mnend; ++mnit) { Mesh::element_group_iterator eg_it = mesh.element_group_find(*mnit); ElementGroup & eg = *eg_it->second; if (eg_it != mesh.element_group_end()) { ElementGroup::type_iterator tit = eg.firstType(); ElementGroup::type_iterator tend = eg.lastType(); for (; tit != tend; ++tit) { Array & abaqus_material = mesh_accessor.getData("abaqus_material", *tit); ElementGroup::const_element_iterator eit = eg.element_begin(*tit); ElementGroup::const_element_iterator eend = eg.element_end(*tit); for (; eit != eend; ++eit) { abaqus_material(*eit) = *mnit; } } } } mesh_accessor.setNbGlobalNodes(mesh.getNodes().getSize()); MeshUtils::fillElementToSubElementsData(mesh); } __END_AKANTU__ diff --git a/src/io/mesh_io/mesh_io_diana.cc b/src/io/mesh_io/mesh_io_diana.cc index 42ea07a41..d24ab83a3 100644 --- a/src/io/mesh_io/mesh_io_diana.cc +++ b/src/io/mesh_io/mesh_io_diana.cc @@ -1,584 +1,584 @@ /** * @file mesh_io_diana.cc * * @author Guillaume Anciaux * @author David Simon Kammer * @author Nicolas Richart * @author Alodie Schneuwly * * @date creation: Sat Mar 26 2011 * @date last modification: Thu Jan 21 2016 * * @brief handles diana meshes * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #include "mesh_io_diana.hh" #include "mesh_utils.hh" #include "element_group.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* Methods Implentations */ /* -------------------------------------------------------------------------- */ MeshIODiana::MeshIODiana() { canReadSurface = true; canReadExtendedData = true; _diana_to_akantu_element_types["T9TM"] = _triangle_3; _diana_to_akantu_element_types["CT6CM"] = _triangle_6; _diana_to_akantu_element_types["Q12TM"] = _quadrangle_4; _diana_to_akantu_element_types["CQ8CM"] = _quadrangle_8; _diana_to_akantu_element_types["TP18L"] = _pentahedron_6; _diana_to_akantu_element_types["CTP45"] = _pentahedron_15; _diana_to_akantu_element_types["TE12L"] = _tetrahedron_4; _diana_to_akantu_element_types["HX24L"] = _hexahedron_8; _diana_to_akantu_element_types["CHX60"] = _hexahedron_20; _diana_to_akantu_mat_prop["YOUNG"] = "E"; _diana_to_akantu_mat_prop["DENSIT"] = "rho"; _diana_to_akantu_mat_prop["POISON"] = "nu"; std::map::iterator it; for (it = _diana_to_akantu_element_types.begin(); it != _diana_to_akantu_element_types.end(); ++it) { UInt nb_nodes = Mesh::getNbNodesPerElement(it->second); UInt * tmp = new UInt[nb_nodes]; for (UInt i = 0; i < nb_nodes; ++i) { tmp[i] = i; } switch (it->second) { case _tetrahedron_10: tmp[8] = 9; tmp[9] = 8; break; case _pentahedron_15: tmp[0] = 2; tmp[1] = 8; tmp[2] = 0; tmp[3] = 6; tmp[4] = 1; tmp[5] = 7; tmp[6] = 11; tmp[7] = 9; tmp[8] = 10; tmp[9] = 5; tmp[10] = 14; tmp[11] = 3; tmp[12] = 12; tmp[13] = 4; tmp[14] = 13; break; case _hexahedron_20: tmp[0] = 5; tmp[1] = 16; tmp[2] = 4; tmp[3] = 19; tmp[4] = 7; tmp[5] = 18; tmp[6] = 6; tmp[7] = 17; tmp[8] = 13; tmp[9] = 12; tmp[10] = 15; tmp[11] = 14; tmp[12] = 1; tmp[13] = 8; tmp[14] = 0; tmp[15] = 11; tmp[16] = 3; tmp[17] = 10; tmp[18] = 2; tmp[19] = 9; break; default: // nothing to change break; } _read_order[it->second] = tmp; } } /* -------------------------------------------------------------------------- */ MeshIODiana::~MeshIODiana() {} /* -------------------------------------------------------------------------- */ inline void my_getline(std::ifstream & infile, std::string & line) { std::getline(infile, line); // read the line size_t pos = line.find("\r"); /// remove the extra \r if needed line = line.substr(0, pos); } /* -------------------------------------------------------------------------- */ void MeshIODiana::read(const std::string & filename, Mesh & mesh) { AKANTU_DEBUG_IN(); std::ifstream infile; infile.open(filename.c_str()); std::string line; UInt first_node_number = std::numeric_limits::max(); diana_element_number_to_elements.clear(); if (!infile.good()) { AKANTU_DEBUG_ERROR("Cannot open file " << filename); } while (infile.good()) { my_getline(infile, line); /// read all nodes if (line == "'COORDINATES'") { line = readCoordinates(infile, mesh, first_node_number); } /// read all elements if (line == "'ELEMENTS'") { line = readElements(infile, mesh, first_node_number); } /// read the material properties and write a .dat file if (line == "'MATERIALS'") { line = readMaterial(infile, filename); } /// read the material properties and write a .dat file if (line == "'GROUPS'") { line = readGroups(infile, mesh, first_node_number); } } infile.close(); mesh.nb_global_nodes = mesh.nodes->getSize(); MeshUtils::fillElementToSubElementsData(mesh); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MeshIODiana::write(__attribute__((unused)) const std::string & filename, __attribute__((unused)) const Mesh & mesh) { AKANTU_DEBUG_TO_IMPLEMENT(); } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readCoordinates(std::ifstream & infile, Mesh & mesh, UInt & first_node_number) { AKANTU_DEBUG_IN(); Array & nodes = const_cast &>(mesh.getNodes()); std::string line; UInt index; Real coord[3]; do { my_getline(infile, line); if ("'ELEMENTS'" == line) break; std::stringstream sstr_node(line); sstr_node >> index >> coord[0] >> coord[1] >> coord[2]; first_node_number = first_node_number < index ? first_node_number : index; nodes.push_back(coord); } while (true); AKANTU_DEBUG_OUT(); return line; } /* -------------------------------------------------------------------------- */ UInt MeshIODiana::readInterval(std::stringstream & line, std::set & interval) { UInt first; line >> first; if (line.fail()) { return 0; } interval.insert(first); UInt second; int dash; dash = line.get(); if (dash == '-') { line >> second; interval.insert(second); return 2; } if (line.fail()) line.clear(std::ios::eofbit); // in case of get at end of the line else line.unget(); return 1; } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readGroups(std::ifstream & infile, Mesh & mesh, UInt first_node_number) { AKANTU_DEBUG_IN(); std::string line; my_getline(infile, line); bool reading_nodes_group = false; while (line != "'SUPPORTS'") { if (line == "NODES") { reading_nodes_group = true; my_getline(infile, line); } if (line == "ELEMEN") { reading_nodes_group = false; my_getline(infile, line); } std::stringstream * str = new std::stringstream(line); UInt id; std::string name; char c; *str >> id >> name >> c; Array * list_ids = new Array(0, 1, name); UInt s = 1; bool end = false; while (!end) { while (!str->eof() && s != 0) { std::set interval; s = readInterval(*str, interval); std::set::iterator it = interval.begin(); if (s == 1) list_ids->push_back(*it); if (s == 2) { UInt first = *it; ++it; UInt second = *it; for (UInt i = first; i <= second; ++i) { list_ids->push_back(i); } } } if (str->fail()) end = true; else { my_getline(infile, line); delete str; str = new std::stringstream(line); } } delete str; if (reading_nodes_group) { NodeGroup & ng = mesh.createNodeGroup(name); for (UInt i = 0; i < list_ids->getSize(); ++i) { UInt node = (*list_ids)(i) - first_node_number; ng.add(node, false); } delete list_ids; } else { ElementGroup & eg = mesh.createElementGroup(name); for (UInt i = 0; i < list_ids->getSize(); ++i) { Element & elem = diana_element_number_to_elements[ (*list_ids)(i)]; if (elem.type != _not_defined) eg.add(elem, false, false); } eg.optimize(); delete list_ids; } my_getline(infile, line); } AKANTU_DEBUG_OUT(); return line; } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readElements(std::ifstream & infile, Mesh & mesh, UInt first_node_number) { AKANTU_DEBUG_IN(); std::string line; my_getline(infile, line); if ("CONNECTIVITY" == line) { line = readConnectivity(infile, mesh, first_node_number); } /// read the line corresponding to the materials if ("MATERIALS" == line) { line = readMaterialElement(infile, mesh); } AKANTU_DEBUG_OUT(); return line; } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readConnectivity(std::ifstream & infile, Mesh & mesh, UInt first_node_number) { AKANTU_DEBUG_IN(); Int index; std::string lline; std::string diana_type; ElementType akantu_type, akantu_type_old = _not_defined; Array * connectivity = NULL; UInt node_per_element = 0; Element elem; UInt * read_order = NULL; while (1) { my_getline(infile, lline); // std::cerr << lline << std::endl; std::stringstream sstr_elem(lline); if (lline == "MATERIALS") break; /// traiter les coordonnees sstr_elem >> index; sstr_elem >> diana_type; akantu_type = _diana_to_akantu_element_types[diana_type]; if (akantu_type == _not_defined) continue; if (akantu_type != akantu_type_old) { connectivity = mesh.getConnectivityPointer(akantu_type); node_per_element = connectivity->getNbComponent(); akantu_type_old = akantu_type; read_order = _read_order[akantu_type]; } UInt * local_connect = new UInt[node_per_element]; // used if element is written on two lines - UInt j_last; + UInt j_last = 0; for (UInt j = 0; j < node_per_element; ++j) { UInt node_index; sstr_elem >> node_index; // check s'il y a pas plus rien après un certain point if (sstr_elem.fail()) { sstr_elem.clear(); sstr_elem.ignore(); break; } node_index -= first_node_number; local_connect[read_order[j]] = node_index; j_last = j; } // check if element is written in two lines if (j_last != (node_per_element - 1)) { // if this is the case, read on more line my_getline(infile, lline); std::stringstream sstr_elem(lline); for (UInt j = (j_last + 1); j < node_per_element; ++j) { UInt node_index; sstr_elem >> node_index; node_index -= first_node_number; local_connect[read_order[j]] = node_index; } } connectivity->push_back(local_connect); elem.type = akantu_type; elem.element = connectivity->getSize() - 1; diana_element_number_to_elements[index] = elem; akantu_number_to_diana_number[elem] = index; delete [] local_connect; } AKANTU_DEBUG_OUT(); return lline; } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readMaterialElement(std::ifstream & infile, Mesh & mesh) { AKANTU_DEBUG_IN(); std::string line; std::stringstream sstr_tag_name; sstr_tag_name << "tag_" << 0; Mesh::type_iterator it = mesh.firstType(); Mesh::type_iterator end = mesh.lastType(); for (; it != end; ++it) { UInt nb_element = mesh.getNbElement(*it); mesh.getDataPointer("material", *it, _not_ghost, 1) ->resize(nb_element); } my_getline(infile, line); while (line != "'MATERIALS'") { line = line.substr(line.find('/') + 1, std::string::npos); // erase the first slash / of the line char tutu[250]; strcpy(tutu, line.c_str()); AKANTU_DEBUG_WARNING("reading line " << line); Array temp_id(0, 2); UInt mat; while (true) { std::stringstream sstr_intervals_elements(line); UInt id[2]; char temp; while (sstr_intervals_elements.good()) { sstr_intervals_elements >> id[0] >> temp >> id[1]; // >> "/" >> mat; if (!sstr_intervals_elements.fail()) temp_id.push_back(id); } if (sstr_intervals_elements.fail()) { sstr_intervals_elements.clear(); sstr_intervals_elements.ignore(); sstr_intervals_elements >> mat; break; } my_getline(infile, line); } // loop over elements // UInt * temp_id_val = temp_id.storage(); for (UInt i = 0; i < temp_id.getSize(); ++i) for (UInt j = temp_id(i, 0); j <= temp_id(i, 1); ++j) { Element & element = diana_element_number_to_elements[j]; if (element.type == _not_defined) continue; UInt elem = element.element; ElementType type = element.type; Array & data = *(mesh.getDataPointer("material", type, _not_ghost)); data(elem) = mat; } my_getline(infile, line); } AKANTU_DEBUG_OUT(); return line; } /* -------------------------------------------------------------------------- */ std::string MeshIODiana::readMaterial(std::ifstream & infile, const std::string & filename) { AKANTU_DEBUG_IN(); std::stringstream mat_file_name; mat_file_name << "material_" << filename; std::ofstream material_file; material_file.open(mat_file_name.str().c_str()); // mat_file_name.str()); UInt mat_index; std::string line; bool first_mat = true; bool end = false; UInt mat_id = 0; typedef std::map MatProp; MatProp mat_prop; do { my_getline(infile, line); std::stringstream sstr_material(line); if (("'GROUPS'" == line) || ("'END'" == line)) { if (!mat_prop.empty()) { material_file << "material elastic [" << std::endl; material_file << "\tname = material" << ++mat_id << std::endl; for (MatProp::iterator it = mat_prop.begin(); it != mat_prop.end(); ++it) material_file << "\t" << it->first << " = " << it->second << std::endl; material_file << "]" << std::endl; mat_prop.clear(); } end = true; } else { /// traiter les caractéristiques des matériaux sstr_material >> mat_index; if (!sstr_material.fail()) { if (!first_mat) { if (!mat_prop.empty()) { material_file << "material elastic [" << std::endl; material_file << "\tname = material" << ++mat_id << std::endl; for (MatProp::iterator it = mat_prop.begin(); it != mat_prop.end(); ++it) material_file << "\t" << it->first << " = " << it->second << std::endl; material_file << "]" << std::endl; mat_prop.clear(); } } first_mat = false; } else { sstr_material.clear(); } std::string prop_name; sstr_material >> prop_name; std::map::iterator it; it = _diana_to_akantu_mat_prop.find(prop_name); if (it != _diana_to_akantu_mat_prop.end()) { Real value; sstr_material >> value; mat_prop[it->second] = value; } else { AKANTU_DEBUG_INFO("In material reader, property " << prop_name << "not recognized"); } } } while (!end); AKANTU_DEBUG_OUT(); return line; } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/src/io/parser/algebraic_parser.hh b/src/io/parser/algebraic_parser.hh index 24af4ebee..1a2e1851b 100644 --- a/src/io/parser/algebraic_parser.hh +++ b/src/io/parser/algebraic_parser.hh @@ -1,562 +1,529 @@ /** * @file algebraic_parser.hh * * @author Nicolas Richart * * @date creation: Wed Nov 13 2013 * @date last modification: Wed Nov 11 2015 * * @brief algebraic_parser definition of the grammar * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ // Boost #include #include -#include -#include -#include +#include #ifndef __AKANTU_ALGEBRAIC_PARSER_HH__ #define __AKANTU_ALGEBRAIC_PARSER_HH__ namespace spirit = boost::spirit; namespace qi = boost::spirit::qi; namespace lbs = boost::spirit::qi::labels; namespace ascii = boost::spirit::ascii; namespace phx = boost::phoenix; namespace akantu { namespace parser { struct algebraic_error_handler_ { template struct result { typedef void type; }; template void operator()(qi::info const& what, Iterator err_pos, Iterator last) const { AKANTU_EXCEPTION("Error! Expecting " << what // what failed? << " here: \"" << std::string(err_pos, last) // iterators to error-pos, end << "\""); } }; static Real my_min(Real a, Real b) { return std::min(a, b); } static Real my_max(Real a, Real b) { return std::max(a, b); } + static Real my_pow(Real a, Real b) { return std::pow(a, b); } + + static Real eval_param(const ID & a, const ParserSection & section) { + return section.getParameter(a, _ppsc_current_and_parent_scope); + } - struct lazy_unary_func_ { - template - struct result { typedef T type; }; - - template - typename result::type operator()(Funct f, T a) const { - return f(a); - } - }; - - struct lazy_binary_func_ { - template - struct result { typedef T1 type; }; - - template - typename result::type operator()(Funct f, T1 a, T2 b) const { - return f(a, b); - } - }; - - struct lazy_pow_ { - template - struct result { typedef T1 type; }; - - template - typename result::type operator()(T1 a, T2 b) const { - return std::pow(a, b); - } - }; - - struct lazy_eval_param_ { - template - struct result { typedef res type; }; - + static Real unary_func(Real (*func)(Real), Real a) { + return func(a); + } - template - res operator()(T1 a, const T2 & section, - __attribute__((unused)) const res & result) const { - return section.getParameter(a, _ppsc_current_and_parent_scope); - } - }; + static Real binary_func(Real (*func)(Real, Real), Real a, Real b) { + return func(a, b); + } + template struct AlgebraicGrammar : qi::grammar { AlgebraicGrammar(const ParserSection & section) : AlgebraicGrammar::base_type(start, "algebraic_grammar"), section(section) { - phx::function const error_handler = algebraic_error_handler_(); - phx::function lazy_pow; - phx::function lazy_unary_func; - phx::function lazy_binary_func; - phx::function lazy_eval_param; + // phx::function lazy_pow; + // phx::function lazy_unary_func; + // phx::function lazy_binary_func; + // phx::function lazy_eval_param; + start = expr.alias() ; expr = term [ lbs::_val = lbs::_1 ] >> *( ('+' > term [ lbs::_val += lbs::_1 ]) | ('-' > term [ lbs::_val -= lbs::_1 ]) ) ; term = factor [ lbs::_val = lbs::_1 ] >> *( ('*' > factor [ lbs::_val *= lbs::_1 ]) | ('/' > factor [ lbs::_val /= lbs::_1 ]) ) ; factor = number [ lbs::_val = lbs::_1 ] - >> *("**" > number [ lbs::_val = lazy_pow(lbs::_val, lbs::_1) ]) + >> *("**" > number [ lbs::_val = phx::bind(&my_pow, lbs::_val, lbs::_1) ]) ; number = real [ lbs::_val = lbs::_1 ] | ('-' > number [ lbs::_val = -lbs::_1 ]) | ('+' > number [ lbs::_val = lbs::_1 ]) | constant [ lbs::_val = lbs::_1 ] | function [ lbs::_val = lbs::_1 ] | ('(' > expr > ')') [ lbs::_val = lbs::_1 ] | variable [ lbs::_val = lbs::_1 ] ; function = (qi::no_case[unary_function] > '(' > expr - > ')') [ lbs::_val = lazy_unary_func(lbs::_1, lbs::_2) ] + > ')') [ lbs::_val = phx::bind(&unary_func, lbs::_1, lbs::_2) ] | (qi::no_case[binary_function] > '(' >> expr > ',' >> expr - > ')') [ lbs::_val = lazy_binary_func(lbs::_1, lbs::_2, lbs::_3) ] + > ')') [ lbs::_val = phx::bind(&binary_func ,lbs::_1, lbs::_2, lbs::_3) ] ; variable - = key [ lbs::_val = lazy_eval_param(lbs::_1, section, lbs::_val) ] + = key [ lbs::_val = phx::bind(&eval_param, lbs::_1, section) ] ; key = qi::no_skip[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")] // coming from the InputFileGrammar ; #ifndef M_PI # define M_PI 3.14159265358979323846 #endif #ifndef M_E # define M_E 2.7182818284590452354 #endif constant.add ("pi", M_PI) ("e", M_E); unary_function.add ("abs" , &std::abs ) ("acos" , &std::acos ) ("asin" , &std::asin ) ("atan" , &std::atan ) ("ceil" , &std::ceil ) ("cos" , &std::cos ) ("cosh" , &std::cosh ) ("exp" , &std::exp ) ("floor" , &std::floor ) ("log10" , &std::log10 ) ("log" , &std::log ) ("sin" , &std::sin ) ("sinh" , &std::sinh ) ("sqrt" , &std::sqrt ) ("tan" , &std::tan ) ("tanh" , &std::tanh ) #if defined(AKANTU_CORE_CXX11 ) ("acosh" , &std::acosh ) ("asinh" , &std::asinh ) ("atanh" , &std::atanh ) ("exp2" , &std::exp2 ) ("expm1" , &std::expm1 ) ("log1p" , &std::log1p ) ("log2" , &std::log2 ) ("erf" , &std::erf ) ("erfc" , &std::erfc ) ("lgamma", &std::lgamma) ("tgamma", &std::tgamma) ("trunc" , &std::trunc ) ("round" , &std::round ) // ("crbt" , &std::crbt ) #endif ; binary_function.add ("pow" , &std::pow ) ("min" , &parser::my_min) ("max" , &parser::my_max) ("atan2", &std::atan2 ) ("fmod" , &std::fmod ) #if defined(AKANTU_CORE_CXX11) ("hypot", &std::hypot ) #endif ; +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) + phx::function const error_handler = algebraic_error_handler_(); qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_2)); - +#endif + expr .name("expression"); term .name("term"); factor .name("factor"); number .name("numerical-value"); variable.name("variable"); function.name("function"); constant.name("constants-list"); unary_function.name("unary-functions-list"); binary_function.name("binary-functions-list"); #if !defined AKANTU_NDEBUG if(AKANTU_DEBUG_TEST(dblDebug)) { qi::debug(expr); qi::debug(term); qi::debug(factor); qi::debug(number); qi::debug(variable); qi::debug(function); } #endif } private: qi::rule start; qi::rule expr; qi::rule term; qi::rule factor; qi::rule number; qi::rule variable; qi::rule function; qi::rule key; qi::real_parser< Real, qi::real_policies > real; qi::symbols constant; qi::symbols unary_function; qi::symbols binary_function; const ParserSection & section; }; /* ---------------------------------------------------------------------- */ /* Vector Parser */ /* ---------------------------------------------------------------------- */ struct parsable_vector { operator Vector() { Vector tmp(_cells.size()); std::vector::iterator it = _cells.begin(); for (UInt i = 0; it != _cells.end(); ++it, ++i) tmp(i) = *it; return tmp; } std::vector _cells; }; inline std::ostream& operator<<(std::ostream& stream, const parsable_vector& pv) { stream << "pv["; std::vector::const_iterator it = pv._cells.begin(); if(it != pv._cells.end()) { stream << *it; for (++it; it != pv._cells.end(); ++it) stream << ", " << *it; } stream << "]"; return stream; } struct parsable_matrix { operator Matrix() { size_t cols = 0; std::vector::iterator it_rows = _cells.begin(); for (;it_rows != _cells.end(); ++it_rows) cols = std::max(cols, it_rows->_cells.size()); Matrix tmp(_cells.size(), _cells[0]._cells.size(), 0.); it_rows = _cells.begin(); for (UInt i = 0; it_rows != _cells.end(); ++it_rows, ++i) { std::vector::iterator it_cols = it_rows->_cells.begin(); for (UInt j = 0; it_cols != it_rows->_cells.end(); ++it_cols, ++j) { tmp(i, j) = *it_cols; } } return tmp; } std::vector _cells; }; inline std::ostream& operator<<(std::ostream& stream, const parsable_matrix& pm) { stream << "pm["; std::vector::const_iterator it = pm._cells.begin(); if(it != pm._cells.end()) { stream << *it; for (++it; it != pm._cells.end(); ++it) stream << ", " << *it; } stream << "]"; return stream; } /* ---------------------------------------------------------------------- */ - struct lazy_cont_add_ { - template - struct result { typedef void type; }; - - template - void operator()(T1 & cont, T2 & value) const { - cont._cells.push_back(value); - } - }; + template + static void cont_add(T1 & cont, T2 & value) { + cont._cells.push_back(value); + } /* ---------------------------------------------------------------------- */ template struct VectorGrammar : qi::grammar { VectorGrammar(const ParserSection & section) : VectorGrammar::base_type(start, "vector_algebraic_grammar"), - number(section) { - phx::function const error_handler = algebraic_error_handler_(); - //phx::function lazy_algebraic_eval; - phx::function lazy_vector_add; + number(section) { start = '[' > vector > ']' ; vector - = ( number [ lazy_vector_add(lbs::_a, lbs::_1) ] + = ( number [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] >> *( ',' - >> number [ lazy_vector_add(lbs::_a, lbs::_1) ] + >> number [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] ) ) [ lbs::_val = lbs::_a ] ; +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) + phx::function const error_handler = algebraic_error_handler_(); qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_2)); +#endif start .name("start"); vector.name("vector"); number.name("value"); #if !defined AKANTU_NDEBUG if(AKANTU_DEBUG_TEST(dblDebug)) { qi::debug(start); qi::debug(vector); } #endif } private: qi::rule start; qi::rule, Skipper> vector; qi::rule value; AlgebraicGrammar number; }; /* ---------------------------------------------------------------------- */ - struct lazy_vector_eval_ { - template - struct result { typedef bool type; }; - - template - bool operator()(T1 a, const T2 & section, res & result) const { - std::string value = section.getParameter(a, _ppsc_current_and_parent_scope); - std::string::const_iterator b = value.begin(); - std::string::const_iterator e = value.end(); - parser::VectorGrammar grammar(section); - return qi::phrase_parse(b, e, grammar, qi::space, result); - } - }; - + static bool vector_eval(const ID & a, const ParserSection & section, parsable_vector & result) { + std::string value = section.getParameter(a, _ppsc_current_and_parent_scope); + std::string::const_iterator b = value.begin(); + std::string::const_iterator e = value.end(); + parser::VectorGrammar grammar(section); + return qi::phrase_parse(b, e, grammar, qi::space, result); + } /* ---------------------------------------------------------------------- */ template struct MatrixGrammar : qi::grammar { MatrixGrammar(const ParserSection & section) : MatrixGrammar::base_type(start, "matrix_algebraic_grammar"), vector(section) { - phx::function const error_handler = algebraic_error_handler_(); - phx::function lazy_vector_eval; - phx::function lazy_matrix_add; start = '[' >> matrix >> ']' ; matrix - = ( rows [ lazy_matrix_add(lbs::_a, lbs::_1) ] + = ( rows [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] >> *( ',' - >> rows [ lazy_matrix_add(lbs::_a, lbs::_1) ] + >> rows [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] ) ) [ lbs::_val = lbs::_a ] ; rows = eval_vector | vector ; eval_vector - = (key [ lbs::_pass = lazy_vector_eval(lbs::_1, section, lbs::_a) ]) [lbs::_val = lbs::_a] + = (key [ lbs::_pass = phx::bind(&vector_eval, + lbs::_1, section, lbs::_a) ]) [lbs::_val = lbs::_a] ; key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9") // coming from the InputFileGrammar ; - +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) + phx::function const error_handler = algebraic_error_handler_(); qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_2)); - +#endif + start .name("matrix"); matrix.name("all_rows"); rows .name("rows"); vector.name("vector"); eval_vector.name("eval_vector"); #ifndef AKANTU_NDEBUG if(AKANTU_DEBUG_TEST(dblDebug)) { qi::debug(start); qi::debug(matrix); qi::debug(rows); qi::debug(eval_vector); qi::debug(key); } #endif } private: qi::rule start; qi::rule, Skipper> matrix; qi::rule rows; qi::rule, Skipper> eval_vector; qi::rule key; VectorGrammar vector; }; /* ---------------------------------------------------------------------- */ /* Randon Generator */ /* ---------------------------------------------------------------------- */ struct ParsableRandomGenerator { ParsableRandomGenerator(Real base = Real(), const RandomDistributionType & type = _rdt_not_defined, const parsable_vector & parameters = parsable_vector()) : base(base), type(type), parameters(parameters) {} Real base; RandomDistributionType type; parsable_vector parameters; }; inline std::ostream& operator<<(std::ostream& stream, const ParsableRandomGenerator& prg) { stream << "prg[" << prg.base << " " << UInt(prg.type) << " " << prg.parameters << "]"; return stream; } /* ---------------------------------------------------------------------- */ template struct RandomGeneratorGrammar : qi::grammar { RandomGeneratorGrammar(const ParserSection & section) : RandomGeneratorGrammar::base_type(start, "random_generator_grammar"), number(section) { - phx::function const error_handler = algebraic_error_handler_(); - phx::function lazy_params_add; start = generator.alias() ; generator = qi::hold[distribution [ lbs::_val = lbs::_1 ] ] | number [ lbs::_val = phx::construct(lbs::_1) ] ; distribution = ( number >> generator_type >> '[' >> generator_params >> ']' ) [ lbs::_val = phx::construct(lbs::_1, lbs::_2, lbs::_3) ] ; generator_params - = ( number [ lazy_params_add(lbs::_a, lbs::_1) ] + = ( number [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] >> *( ',' - > number [ lazy_params_add(lbs::_a, lbs::_1) ] + > number [ phx::bind(&cont_add, + lbs::_a, lbs::_1) ] ) ) [ lbs::_val = lbs::_a ] ; #define AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD(r, data, elem) \ (BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem)), \ AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))) generator_type.add BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD, _, AKANTU_RANDOM_DISTRIBUTION_TYPES); #undef AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD - +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) + phx::function const error_handler = algebraic_error_handler_(); qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_2)); - +#endif + start .name("random-generator"); generator .name("random-generator"); distribution .name("random-distribution"); generator_type .name("generator-type"); generator_params.name("generator-parameters"); number .name("number"); #ifndef AKANTU_NDEBUG if(AKANTU_DEBUG_TEST(dblDebug)) { qi::debug(generator); qi::debug(distribution); qi::debug(generator_params); } #endif } private: qi::rule start; qi::rule generator; qi::rule distribution; qi::rule, Skipper> generator_params; AlgebraicGrammar number; qi::symbols generator_type; }; } } #endif /* __AKANTU_ALGEBRAIC_PARSER_HH__ */ diff --git a/src/io/parser/input_file_parser.hh b/src/io/parser/input_file_parser.hh index 24385b554..5de9a409b 100644 --- a/src/io/parser/input_file_parser.hh +++ b/src/io/parser/input_file_parser.hh @@ -1,289 +1,266 @@ /** * @file input_file_parser.hh * * @author Nicolas Richart * * @date creation: Wed Nov 13 2013 * @date last modification: Tue May 19 2015 * * @brief Grammar definition for the input files * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ // Boost /* -------------------------------------------------------------------------- */ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include -//#include #ifndef __AKANTU_INPUT_FILE_PARSER_HH__ #define __AKANTU_INPUT_FILE_PARSER_HH__ namespace spirit = boost::spirit; namespace qi = boost::spirit::qi; namespace lbs = boost::spirit::qi::labels; namespace ascii = boost::spirit::ascii; namespace phx = boost::phoenix; __BEGIN_AKANTU__ namespace parser { -struct error_handler_ { - template struct result { - typedef void type; - }; - - template - void operator()(qi::info const & what, Iterator err_pos, - __attribute__((unused)) Iterator first, - __attribute__((unused)) Iterator last) const { - spirit::classic::file_position pos = err_pos.get_position(); - - AKANTU_EXCEPTION("Parse error [ " - << "Expecting " << what << " instead of \"" << *err_pos - << "\" ]" - << " in file " << pos.file << " line " << pos.line - << " column " << pos.column << std::endl - << "'" << err_pos.get_currentline() << "'" << std::endl - << std::setw(pos.column) << " " - << "^- here"); - } - -private: -}; + struct error_handler_ { + template struct result { + typedef void type; + }; + + template + void operator()(qi::info const & what, Iterator err_pos, + __attribute__((unused)) Iterator first, + __attribute__((unused)) Iterator last) const { + spirit::classic::file_position pos = err_pos.get_position(); + + AKANTU_EXCEPTION("Parse error [ " + << "Expecting " << what << " instead of \"" << *err_pos + << "\" ]" + << " in file " << pos.file << " line " << pos.line + << " column " << pos.column << std::endl + << "'" << err_pos.get_currentline() << "'" << std::endl + << std::setw(pos.column) << " " + << "^- here"); + } -struct lazy_create_subsection_ { - template struct result { - typedef ParserSection & type; + private: }; - template - ParserSection & operator()(const SectionType & type, const std::string & name, - const T & option, ParserSection & sect) const { - std::string opt; - if (option) - opt = *option; + static ParserSection & create_subsection(const SectionType & type, + const std::string & name, + const boost::optional & option, + ParserSection & sect) { + std::string opt = ""; + if (option) opt = *option; + ParserSection sect_tmp(name, type, opt, sect); return sect.addSubSection(sect_tmp); } -}; - -template struct lazy_create_parameter_ { - lazy_create_parameter_(std::string & error_message) - : error_message(error_message) {} - template struct result { typedef bool type; }; - - template - bool operator()(const Range & rng, const std::string & value, - ParserSection & sect) const { + + template + static bool create_parameter(boost::iterator_range & rng, + std::string & value, + ParserSection & sect) { try { std::string name(rng.begin(), rng.end()); name = trim(name); spirit::classic::file_position pos = rng.begin().get_position(); ParserParameter param_tmp(name, value, sect); param_tmp.setDebugInfo(pos.file, pos.line, pos.column); sect.addParameter(param_tmp); - } catch (debug::Exception & e) { - error_message = e.info(); return false; } return true; } -private: - std::string & error_message; -}; - -struct lazy_concatenate_ { - template struct result { typedef T1 type; }; - - template - T1 operator()(const T1 & t1, const T2 & t2) const { + static std::string concatenate(const std::string & t1, const std::string & t2) { return (t1 + t2); } -}; + /* ---------------------------------------------------------------------- */ /* Grammars definitions */ /* ---------------------------------------------------------------------- */ template struct InputFileGrammar : qi::grammar::type> { InputFileGrammar(ParserSection * sect) : InputFileGrammar::base_type(start, "input_file_grammar"), parent_section(sect) { - phx::function const error_handler = error_handler_(); - phx::function > lazy_create_parameter = - lazy_create_parameter_(error_message); - phx::function lazy_create_subsection; - phx::function lazy_concatenate; /* clang-format off */ start = mini_section(parent_section) ; mini_section = *( entry (lbs::_r1) | section(lbs::_r1) ) ; entry = ( qi::raw[key] >> '=' > value - ) [ lbs::_pass = lazy_create_parameter(lbs::_1, - lbs::_2, - *lbs::_r1) ] + ) [ lbs::_pass = phx::bind(&create_parameter, + lbs::_1, + lbs::_2, + *lbs::_r1) ] ; section = ( qi::no_case[section_type] > qi::lexeme [ section_name > -section_option ] - ) [ lbs::_a = &lazy_create_subsection(lbs::_1, - phx::at_c<0>(lbs::_2), - phx::at_c<1>(lbs::_2), - *lbs::_r1) ] + ) [ lbs::_a = &phx::bind(&create_subsection, + lbs::_1, + phx::at_c<0>(lbs::_2), + phx::at_c<1>(lbs::_2), + *lbs::_r1) ] > '[' > mini_section(lbs::_a) > ']' ; section_name = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9") ; section_option = (+ascii::space >> section_name) [ lbs::_val = lbs::_2 ] ; key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9") ; value = ( - mono_line_value [ lbs::_a = lazy_concatenate(lbs::_a, lbs::_1) ] + mono_line_value [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ] > *( - '\\' > mono_line_value [ lbs::_a = lazy_concatenate(lbs::_a, lbs::_1) ] + '\\' > mono_line_value [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ] ) ) [ lbs::_val = lbs::_a ] ; mono_line_value = qi::lexeme [ +(qi::char_ - (qi::char_('=') | spirit::eol | '#' | ';' | '\\')) ] ; skipper = ascii::space | "#" >> *(qi::char_ - spirit::eol) ; /* clang-format on */ #define AKANTU_SECTION_TYPE_ADD(r, data, elem) \ (BOOST_PP_STRINGIZE(elem), AKANTU_SECTION_TYPES_PREFIX(elem)) section_type.add BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_ADD, _, AKANTU_SECTION_TYPES); #undef AKANTU_SECTION_TYPE_ADD +#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11) + phx::function const error_handler = error_handler_(); qi::on_error(start, error_handler(lbs::_4, lbs::_3, lbs::_1, lbs::_2)); +#endif section.name("section"); section_name.name("section-name"); section_option.name("section-option"); mini_section.name("section-content"); entry.name("parameter"); key.name("parameter-name"); value.name("parameter-value"); section_type.name("section-types-list"); mono_line_value.name("mono-line-value"); #if !defined AKANTU_NDEBUG if (AKANTU_DEBUG_TEST(dblDebug)) { // qi::debug(section); qi::debug(section_name); qi::debug(section_option); // qi::debug(mini_section); // qi::debug(entry); qi::debug(key); qi::debug(value); qi::debug(mono_line_value); } #endif } const std::string & getErrorMessage() const { return error_message; }; typedef typename Skipper::type skipper_type; skipper_type skipper; private: std::string error_message; qi::rule mini_section; qi::rule, skipper_type> section; qi::rule start; qi::rule section_name; qi::rule section_option; qi::rule entry; qi::rule key; qi::rule, skipper_type> value; qi::rule mono_line_value; qi::symbols section_type; ParserSection * parent_section; }; } + __END_AKANTU__ #endif /* __AKANTU_INPUT_FILE_PARSER_HH__ */ diff --git a/src/io/parser/parser_input_files.cc b/src/io/parser/parser_input_files.cc index aaf08d3cd..776157bf0 100644 --- a/src/io/parser/parser_input_files.cc +++ b/src/io/parser/parser_input_files.cc @@ -1,97 +1,120 @@ /** * @file parser_input_files.cc * * @author Nicolas Richart * * @date creation: Wed Nov 11 2015 * @date last modification: Wed Jan 13 2016 * * @brief implementation of the parser * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif (defined(__GNUC__) || defined(__GNUG__)) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + /* -------------------------------------------------------------------------- */ #include "parser.hh" #include "parser_grammar_tmpl.hh" /* -------------------------------------------------------------------------- */ #include "input_file_parser.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ void Parser::parse(const std::string & filename) { this->clean(); std::ifstream input(filename.c_str()); if (!input.good()) { AKANTU_EXCEPTION("Could not open file " << filename << "!"); } input.unsetf(std::ios::skipws); // wrap istream into iterator spirit::istream_iterator fwd_begin(input); spirit::istream_iterator fwd_end; // wrap forward iterator with position iterator, to record the position typedef spirit::classic::position_iterator2 pos_iterator_type; pos_iterator_type position_begin(fwd_begin, fwd_end, filename); pos_iterator_type position_end; // parse parser::InputFileGrammar ag(this); bool result = qi::phrase_parse(position_begin, position_end, ag, ag.skipper); if (!result || position_begin != position_end) { spirit::classic::file_position pos = position_begin.get_position(); AKANTU_EXCEPTION("Parse error [ " << ag.getErrorMessage() << " ]" << " in file " << filename << " line " << pos.line << " column " << pos.column << std::endl << "'" << position_begin.get_currentline() << "'" << std::endl << std::setw(pos.column) << " " << "^- here"); } try { DebugLevel dbl = debug::getDebugLevel(); debug::setDebugLevel(dblError); bool permissive = getParameter("permissive_parser", _ppsc_current_scope); debug::setDebugLevel(dbl); permissive_parser = permissive; AKANTU_DEBUG_INFO("Parser switched permissive mode to " << std::boolalpha << permissive_parser); } catch (debug::Exception & e) { } last_parsed_file = filename; input.close(); } __END_AKANTU__ + +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif defined(__GNUG__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic pop +# else +# pragma GCC diagnostic warning "-Wunused-local-typedefs" +# endif +#endif + diff --git a/src/io/parser/parser_random.cc b/src/io/parser/parser_random.cc index 7f281cdea..c17d43714 100644 --- a/src/io/parser/parser_random.cc +++ b/src/io/parser/parser_random.cc @@ -1,58 +1,69 @@ /** * @file parser_random.cc * * @author Nicolas Richart * * @date creation: Thu Feb 21 2013 * @date last modification: Mon Dec 07 2015 * * @brief implementation of the parser * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif (defined(__GNUC__) || defined(__GNUG__)) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + /* -------------------------------------------------------------------------- */ #include "parser.hh" #include "parser_grammar_tmpl.hh" /* -------------------------------------------------------------------------- */ #include "algebraic_parser.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ RandomParameter Parser::parseRandomParameter(const std::string & value, const ParserSection & section) { using boost::spirit::ascii::space_type; parser::RandomGeneratorGrammar grammar(section); grammar.name("random_grammar"); parser::ParsableRandomGenerator rg = Parser::parseType(value, grammar); Vector params = rg.parameters; switch(rg.type) { case _rdt_not_defined: return RandomParameter(rg.base); case _rdt_uniform: return RandomParameter(rg.base, UniformDistribution(params(0), params(1))); case _rdt_weibull: return RandomParameter(rg.base, WeibullDistribution(params(0), params(1))); default: AKANTU_EXCEPTION("This is an unknown random distribution in the parser"); } } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/src/io/parser/parser_real.cc b/src/io/parser/parser_real.cc index 666d8f0ce..accd1ff36 100644 --- a/src/io/parser/parser_real.cc +++ b/src/io/parser/parser_real.cc @@ -1,48 +1,59 @@ /** * @file parser_real.cc * * @author Nicolas Richart * * @date creation: Thu Feb 21 2013 * @date last modification: Wed Nov 11 2015 * * @brief implementation of the parser * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif (defined(__GNUC__) || defined(__GNUG__)) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + /* -------------------------------------------------------------------------- */ #include "parser.hh" #include "parser_grammar_tmpl.hh" /* -------------------------------------------------------------------------- */ #include "algebraic_parser.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ Real Parser::parseReal(const std::string & value, const ParserSection & section) { using boost::spirit::ascii::space_type; parser::AlgebraicGrammar grammar(section); grammar.name("algebraic_grammar"); return Parser::parseType(value, grammar); } -__END_AKANTU__ \ No newline at end of file +__END_AKANTU__ diff --git a/src/io/parser/parser_types.cc b/src/io/parser/parser_types.cc index f829f7279..a30bcf903 100644 --- a/src/io/parser/parser_types.cc +++ b/src/io/parser/parser_types.cc @@ -1,58 +1,69 @@ /** * @file parser_types.cc * * @author Nicolas Richart * * @date creation: Thu Feb 21 2013 * @date last modification: Wed Nov 11 2015 * * @brief implementation of the parser * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ +#if defined(__INTEL_COMPILER) +//#pragma warning ( disable : 383 ) +#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +#elif (defined(__GNUC__) || defined(__GNUG__)) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if GCC_VERSION > 40600 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + /* -------------------------------------------------------------------------- */ #include "parser.hh" #include "parser_grammar_tmpl.hh" /* -------------------------------------------------------------------------- */ #include "algebraic_parser.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ Vector Parser::parseVector(const std::string & value, const ParserSection & section) { using boost::spirit::ascii::space_type; parser::VectorGrammar grammar(section); grammar.name("vector_grammar"); return Parser::parseType(value, grammar); } /* -------------------------------------------------------------------------- */ Matrix Parser::parseMatrix(const std::string & value, const ParserSection & section) { using boost::spirit::ascii::space_type; parser::MatrixGrammar grammar(section); grammar.name("matrix_grammar"); return Parser::parseType(value, grammar); } /* -------------------------------------------------------------------------- */ -__END_AKANTU__ \ No newline at end of file +__END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc index ecd5157a6..4c3f425d4 100644 --- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc +++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc @@ -1,349 +1,331 @@ /** * @file material_elastic_linear_anisotropic.cc * * @author Till Junge * @author Nicolas Richart * * @date creation: Wed Sep 25 2013 * @date last modification: Thu Oct 15 2015 * * @brief Anisotropic elastic material * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #include "material_elastic_linear_anisotropic.hh" #include "solid_mechanics_model.hh" #include #include __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ template MaterialElasticLinearAnisotropic:: MaterialElasticLinearAnisotropic(SolidMechanicsModel & model, const ID & id, bool symmetric) : Material(model, id), rot_mat(spatial_dimension, spatial_dimension), Cprime(spatial_dimension*spatial_dimension, spatial_dimension*spatial_dimension), C(this->voigt_h.size, this->voigt_h.size), eigC(this->voigt_h.size), symmetric(symmetric), alpha(0) { AKANTU_DEBUG_IN(); this->dir_vecs.push_back(new Vector(spatial_dimension)); (*this->dir_vecs.back())[0] = 1.; this->registerParam("n1", *(this->dir_vecs.back()), _pat_parsmod, "Direction of main material axis"); this->dir_vecs.push_back(new Vector(spatial_dimension)); (*this->dir_vecs.back())[1] = 1.; this->registerParam("n2", *(this->dir_vecs.back()), _pat_parsmod, "Direction of secondary material axis"); if (spatial_dimension > 2) { this->dir_vecs.push_back(new Vector(spatial_dimension)); (*this->dir_vecs.back())[2] = 1.; this->registerParam("n3", *(this->dir_vecs.back()), _pat_parsmod, "Direction of tertiary material axis"); } for (UInt i = 0 ; i < this->voigt_h.size ; ++i) { UInt start = 0; if (this->symmetric) { start = i; } for (UInt j = start ; j < this->voigt_h.size ; ++j) { std::stringstream param("C"); param << "C" << i+1 << j+1; this->registerParam(param.str() , this->Cprime(i,j), Real(0.), _pat_parsmod, "Coefficient " + param.str()); } } this->registerParam("alpha", this->alpha, _pat_parsmod, "Proportion of viscous stress"); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template MaterialElasticLinearAnisotropic::~MaterialElasticLinearAnisotropic() { for (UInt i = 0 ; i < spatial_dimension ; ++i) { delete this->dir_vecs[i]; } } /* -------------------------------------------------------------------------- */ template void MaterialElasticLinearAnisotropic::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); updateInternalParameters(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void MaterialElasticLinearAnisotropic::updateInternalParameters() { Material::updateInternalParameters(); if (this->symmetric) { for (UInt i = 0 ; i < this->voigt_h.size ; ++i) { for (UInt j = i+1 ; j < this->voigt_h.size ; ++j) { this->Cprime(j, i) = this->Cprime(i, j); } } } this->rotateCprime(); this->C.eig(this->eigC); } /* -------------------------------------------------------------------------- */ template void MaterialElasticLinearAnisotropic::rotateCprime() { // start by filling the empty parts fo Cprime UInt diff = Dim*Dim - this->voigt_h.size; for (UInt i = this->voigt_h.size ; i < Dim*Dim ; ++i) { for (UInt j = 0 ; j < Dim*Dim ; ++j) { this->Cprime(i, j) = this->Cprime(i-diff, j); } } for (UInt i = 0 ; i < Dim*Dim ; ++i) { for (UInt j = this->voigt_h.size ; j < Dim*Dim ; ++j) { this->Cprime(i, j) = this->Cprime(i, j-diff); } } // construction of rotator tensor // normalise rotation matrix for (UInt j = 0 ; j < Dim ; ++j) { Vector rot_vec = this->rot_mat(j); rot_vec = *this->dir_vecs[j]; rot_vec.normalize(); } // make sure the vectors form a right-handed base Vector test_axis(3); Vector v1(3), v2(3), v3(3); if (Dim == 2){ for (UInt i = 0; i < Dim; ++i) { v1[i] = this->rot_mat(0, i); v2[i] = this->rot_mat(1, i); v3[i] = 0.; } v3[2] = 1.; v1[2] = 0.; v2[2] = 0.; } else if (Dim == 3){ v1 = this->rot_mat(0); v2 = this->rot_mat(1); v3 = this->rot_mat(2); } test_axis.crossProduct(v1,v2); test_axis -= v3; if (test_axis.norm() > 8*std::numeric_limits::epsilon()) { AKANTU_DEBUG_ERROR("The axis vectors do not form a right-handed coordinate " << "system. I. e., ||n1 x n2 - n3|| should be zero, but " << "it is " << test_axis.norm() << "."); } // create the rotator and the reverse rotator Matrix rotator(Dim * Dim, Dim * Dim); Matrix revrotor(Dim * Dim, Dim * Dim); for (UInt i = 0 ; i < Dim ; ++i) { for (UInt j = 0 ; j < Dim ; ++j) { for (UInt k = 0 ; k < Dim ; ++k) { for (UInt l = 0 ; l < Dim ; ++l) { UInt I = this->voigt_h.mat[i][j]; UInt J = this->voigt_h.mat[k][l]; rotator (I, J) = this->rot_mat(k, i) * this->rot_mat(l, j); revrotor(I, J) = this->rot_mat(i, k) * this->rot_mat(j, l); } } } } -#ifndef AKANTU_NDEBUG - Matrix eig_vectors_before(Dim*Dim, Dim * Dim); - Matrix eig_vectors_after(Dim*Dim, Dim * Dim); - Vector eig_val_before(Dim * Dim); - Vector eig_val_after(Dim*Dim); - Cprime.eig(eig_val_before, eig_vectors_before); -#endif // create the full rotated matrix Matrix Cfull(Dim*Dim, Dim*Dim); Cfull = rotator*Cprime*revrotor; for (UInt i = 0 ; i < this->voigt_h.size ; ++i) { for (UInt j = 0 ; j < this->voigt_h.size ; ++j) { this->C(i, j) = Cfull(i, j); } } - -#ifndef AKANTU_NDEBUG - Cfull.eig(eig_val_after, eig_vectors_after); - AKANTU_DEBUG_ASSERT(eig_val_before.equal(eig_val_after), "The eigenvalues have changed during the rotation"); - Vector eigen_vector(Dim * Dim); - for(UInt i = 0; i < Dim * Dim; ++i) { - eigen_vector = eig_vectors_before(i); - AKANTU_DEBUG_ASSERT(eigen_vector.equal(eig_vectors_after(i)), "The eigenvectors have changed during the rotation"); - } -#endif - } /* -------------------------------------------------------------------------- */ template void MaterialElasticLinearAnisotropic::computeStress(ElementType el_type, GhostType ghost_type) { // Wikipedia convention: // 2*eps_ij (i!=j) = voigt_eps_I // http://en.wikipedia.org/wiki/Voigt_notation AKANTU_DEBUG_IN(); Array::iterator< Matrix > gradu_it = this->gradu(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Array::iterator< Matrix > gradu_end = this->gradu(el_type, ghost_type).end(spatial_dimension, spatial_dimension); UInt nb_quad_pts = gradu_end - gradu_it; // create array for strains and stresses of all dof of all gauss points // for efficient computation of stress Matrix voigt_strains(this->voigt_h.size, nb_quad_pts); Matrix voigt_stresses(this->voigt_h.size, nb_quad_pts); // copy strains Matrix strain(spatial_dimension, spatial_dimension); for (UInt q = 0; gradu_it != gradu_end ; ++gradu_it, ++q) { Matrix & grad_u = *gradu_it; for(UInt I = 0; I < this->voigt_h.size; ++I) { Real voigt_factor = this->voigt_h.factors[I]; UInt i = this->voigt_h.vec[I][0]; UInt j = this->voigt_h.vec[I][1]; voigt_strains(I, q) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.; } } // compute the strain rate proportional part if needed //bool viscous = this->alpha == 0.; // only works if default value bool viscous = false; if(viscous) { Array strain_rate(0, spatial_dimension * spatial_dimension, "strain_rate"); Array & velocity = this->model->getVelocity(); const Array & elem_filter = this->element_filter(el_type, ghost_type); this->model->getFEEngine().gradientOnIntegrationPoints(velocity, strain_rate, spatial_dimension, el_type, ghost_type, elem_filter); Array::matrix_iterator gradu_dot_it = strain_rate.begin(spatial_dimension, spatial_dimension); Array::matrix_iterator gradu_dot_end = strain_rate.end(spatial_dimension, spatial_dimension); Matrix strain_dot(spatial_dimension, spatial_dimension); for (UInt q = 0; gradu_dot_it != gradu_dot_end ; ++gradu_dot_it, ++q) { Matrix & grad_u_dot = *gradu_dot_it; for(UInt I = 0; I < this->voigt_h.size; ++I) { Real voigt_factor = this->voigt_h.factors[I]; UInt i = this->voigt_h.vec[I][0]; UInt j = this->voigt_h.vec[I][1]; voigt_strains(I, q) = this->alpha * voigt_factor * (grad_u_dot(i, j) + grad_u_dot(j, i)) / 2.; } } } // compute stresses voigt_stresses = this->C * voigt_strains; // copy stresses back Array::iterator< Matrix > stress_it = this->stress(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Array::iterator< Matrix > stress_end = this->stress(el_type, ghost_type).end(spatial_dimension, spatial_dimension); for (UInt q = 0 ; stress_it != stress_end; ++stress_it, ++q) { Matrix & stress = *stress_it; for(UInt I = 0; I < this->voigt_h.size; ++I) { UInt i = this->voigt_h.vec[I][0]; UInt j = this->voigt_h.vec[I][1]; stress(i, j) = stress(j, i) = voigt_stresses(I, q); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void MaterialElasticLinearAnisotropic::computeTangentModuli(const ElementType & el_type, Array & tangent_matrix, GhostType ghost_type) { AKANTU_DEBUG_IN(); MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix); tangent.copy(this->C); MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template Real MaterialElasticLinearAnisotropic::getCelerity(__attribute__((unused)) const Element & element) const { return std::sqrt( this->eigC(0) / rho); } /* -------------------------------------------------------------------------- */ INSTANTIATE_MATERIAL(MaterialElasticLinearAnisotropic); __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh index 65aeda8be..e4e3abd75 100644 --- a/src/model/solid_mechanics/materials/material_thermal.hh +++ b/src/model/solid_mechanics/materials/material_thermal.hh @@ -1,105 +1,106 @@ /** * @file material_thermal.hh * * @author Lucas Frerot * * @date creation: Fri Jun 18 2010 * @date last modification: Tue Aug 18 2015 * * @brief Material isotropic thermo-elastic * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_THERMAL_HH__ #define __AKANTU_MATERIAL_THERMAL_HH__ __BEGIN_AKANTU__ template class MaterialThermal : public virtual Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: MaterialThermal(SolidMechanicsModel & model, const ID & id = ""); MaterialThermal(SolidMechanicsModel & model, UInt dim, const Mesh & mesh, FEEngine & fe_engine, const ID & id = ""); virtual ~MaterialThermal() {}; protected: void initialize(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: virtual void initMaterial(); /// constitutive law for all element of a type virtual void computeStress(ElementType el_type, GhostType ghost_type); /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// Young modulus Real E; /// Poisson ratio Real nu; /// Thermal expansion coefficient /// TODO : implement alpha as a matrix Real alpha; /// Temperature field InternalField delta_T; /// Current thermal stress InternalField sigma_th; /// Tell if we need to use the previous thermal stress bool use_previous_stress_thermal; }; __END_AKANTU__ #endif /* __AKANTU_MATERIAL_THERMAL_HH__ */ diff --git a/src/synchronizer/mpi_type_wrapper.hh b/src/synchronizer/mpi_type_wrapper.hh index 21b83205e..9d2b83a5c 100644 --- a/src/synchronizer/mpi_type_wrapper.hh +++ b/src/synchronizer/mpi_type_wrapper.hh @@ -1,99 +1,109 @@ /** * @file mpi_type_wrapper.hh * * @author Nicolas Richart * * @date creation: Mon Jun 14 2010 * @date last modification: Wed Oct 07 2015 * * @brief Wrapper on MPI types to have a better separation between libraries * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifdef AKANTU_USE_MPI #if defined(__INTEL_COMPILER) //#pragma warning ( disable : 383 ) #elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu #elif (defined(__GNUC__) || defined(__GNUG__)) # if __cplusplus > 199711L # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wliteral-suffix" # endif #endif # include #if defined(__INTEL_COMPILER) //#pragma warning ( disable : 383 ) #elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu #elif (defined(__GNUC__) || defined(__GNUG__)) # if __cplusplus > 199711L # pragma GCC diagnostic pop # endif #endif #endif /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "static_communicator_mpi.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MPI_TYPE_WRAPPER_HH__ #define __AKANTU_MPI_TYPE_WRAPPER_HH__ __BEGIN_AKANTU__ class MPITypeWrapper { public: - MPITypeWrapper(StaticCommunicatorMPI & static_comm) : static_comm(static_comm) { + MPITypeWrapper(StaticCommunicatorMPI & static_comm) : static_comm(static_comm), max_tag(0) { } template static inline MPI_Datatype getMPIDatatype(); inline void setMPICommunicator(MPI_Comm comm) { communicator = comm; int prank, psize; MPI_Comm_rank(communicator, &prank); MPI_Comm_size(communicator, &psize); static_comm.setRank(prank); static_comm.setSize(psize); + + int flag; + int *value; + MPI_Comm_get_attr(comm, MPI_TAG_UB, &value, &flag); + AKANTU_DEBUG_ASSERT(flag, "No attribute MPI_TAG_UB."); + this->max_tag = *value; } inline MPI_Comm getMPICommunicator() const { return communicator; } static MPI_Op getMPISynchronizerOperation(const SynchronizerOperation & op) { return synchronizer_operation_to_mpi_op[op]; } + + inline int getMaxTag() const { return this->max_tag; } private: StaticCommunicatorMPI & static_comm; MPI_Comm communicator; + int max_tag; + static MPI_Op synchronizer_operation_to_mpi_op[_so_null + 1]; }; __END_AKANTU__ #endif /* __AKANTU_MPI_TYPE_WRAPPER_HH__ */ diff --git a/src/synchronizer/static_communicator_mpi.cc b/src/synchronizer/static_communicator_mpi.cc index a79aa0525..b0bc97bae 100644 --- a/src/synchronizer/static_communicator_mpi.cc +++ b/src/synchronizer/static_communicator_mpi.cc @@ -1,503 +1,505 @@ /** * @file static_communicator_mpi.cc * * @author Nicolas Richart * * @date creation: Sun Sep 26 2010 * @date last modification: Thu Jan 21 2016 * * @brief StaticCommunicatorMPI implementation * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "static_communicator_mpi.hh" #include "mpi_type_wrapper.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ MPI_Op MPITypeWrapper::synchronizer_operation_to_mpi_op[_so_null + 1] = { MPI_SUM, MPI_MIN, MPI_MAX, MPI_PROD, MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR, MPI_MINLOC, MPI_MAXLOC, MPI_OP_NULL}; class CommunicationRequestMPI : public CommunicationRequest { public: CommunicationRequestMPI(UInt source, UInt dest); ~CommunicationRequestMPI(); MPI_Request * getMPIRequest() { return request; }; private: MPI_Request * request; }; /* -------------------------------------------------------------------------- */ /* Implementation */ /* -------------------------------------------------------------------------- */ CommunicationRequestMPI::CommunicationRequestMPI(UInt source, UInt dest) : CommunicationRequest(source, dest) { request = new MPI_Request; } /* -------------------------------------------------------------------------- */ CommunicationRequestMPI::~CommunicationRequestMPI() { delete request; } /* -------------------------------------------------------------------------- */ StaticCommunicatorMPI::StaticCommunicatorMPI(int & argc, char **& argv) : RealStaticCommunicator(argc, argv) { int is_initialized = false; MPI_Initialized(&is_initialized); if (!is_initialized) { MPI_Init(&argc, &argv); } this->is_externaly_initialized = is_initialized; mpi_data = new MPITypeWrapper(*this); mpi_data->setMPICommunicator(MPI_COMM_WORLD); } /* -------------------------------------------------------------------------- */ StaticCommunicatorMPI::~StaticCommunicatorMPI() { if (!this->is_externaly_initialized) { MPI_Finalize(); delete this->mpi_data; } } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::send(T * buffer, Int size, Int receiver, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Send(buffer, size, type, receiver, tag, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Send."); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::receive(T * buffer, Int size, Int sender, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Status status; MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Recv(buffer, size, type, sender, tag, communicator, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Recv."); } /* -------------------------------------------------------------------------- */ template CommunicationRequest * StaticCommunicatorMPI::asyncSend(T * buffer, Int size, Int receiver, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); CommunicationRequestMPI * request = new CommunicationRequestMPI(prank, receiver); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Isend(buffer, size, type, receiver, tag, communicator, request->getMPIRequest()); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Isend."); return request; } /* -------------------------------------------------------------------------- */ template CommunicationRequest * StaticCommunicatorMPI::asyncReceive(T * buffer, Int size, Int sender, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); CommunicationRequestMPI * request = new CommunicationRequestMPI(sender, prank); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Irecv(buffer, size, type, sender, tag, communicator, request->getMPIRequest()); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Irecv."); return request; } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::probe(Int sender, Int tag, CommunicationStatus & status) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Status mpi_status; #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Probe(sender, tag, communicator, &mpi_status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Probe."); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); int count; MPI_Get_count(&mpi_status, type, &count); status.setSource(mpi_status.MPI_SOURCE); status.setTag(mpi_status.MPI_TAG); status.setSize(count); } /* -------------------------------------------------------------------------- */ bool StaticCommunicatorMPI::testRequest(CommunicationRequest * request) { MPI_Status status; int flag; CommunicationRequestMPI * req_mpi = static_cast(request); MPI_Request * req = req_mpi->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Test(req, &flag, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Test."); return (flag != 0); } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::wait(CommunicationRequest * request) { MPI_Status status; CommunicationRequestMPI * req_mpi = static_cast(request); MPI_Request * req = req_mpi->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Wait(req, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Wait."); } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::waitAll( std::vector & requests) { MPI_Status status; std::vector::iterator it; for (it = requests.begin(); it != requests.end(); ++it) { MPI_Request * req = static_cast(*it)->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Wait(req, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Wait."); } } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::barrier() { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Barrier(communicator); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::reduce(T * values, int nb_values, const SynchronizerOperation & op, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Reduce(MPI_IN_PLACE, values, nb_values, type, MPITypeWrapper::getMPISynchronizerOperation(op), root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce."); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::allReduce(T * values, int nb_values, const SynchronizerOperation & op) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type, MPITypeWrapper::getMPISynchronizerOperation(op), communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce."); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::allGather(T * values, int nb_values) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allgather(MPI_IN_PLACE, nb_values, type, values, nb_values, type, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allgather."); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::allGatherV(T * values, int * nb_values) { MPI_Comm communicator = mpi_data->getMPICommunicator(); int * displs = new int[psize]; displs[0] = 0; for (int i = 1; i < psize; ++i) { displs[i] = displs[i - 1] + nb_values[i - 1]; } MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allgatherv(MPI_IN_PLACE, *nb_values, type, values, nb_values, displs, type, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); delete[] displs; } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::gather(T * values, int nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); T * send_buf = NULL, * recv_buf = NULL; if (prank == root) { send_buf = (T *)MPI_IN_PLACE; recv_buf = values; } else { send_buf = values; } MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Gather(send_buf, nb_values, type, recv_buf, nb_values, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::gatherV(T * values, int * nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); int * displs = NULL; if (prank == root) { displs = new int[psize]; displs[0] = 0; for (int i = 1; i < psize; ++i) { displs[i] = displs[i - 1] + nb_values[i - 1]; } } T * send_buf = NULL, * recv_buf = NULL; if (prank == root) { send_buf = (T *)MPI_IN_PLACE; recv_buf = values; } else send_buf = values; MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Gatherv(send_buf, *nb_values, type, recv_buf, nb_values, displs, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); if (prank == root) { delete[] displs; } } /* -------------------------------------------------------------------------- */ template void StaticCommunicatorMPI::broadcast(T * values, int nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Bcast(values, nb_values, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); } /* -------------------------------------------------------------------------- */ -int StaticCommunicatorMPI::getMaxTag() { return MPI_TAG_UB; } +int StaticCommunicatorMPI::getMaxTag() { + return this->mpi_data->getMaxTag(); +} /* -------------------------------------------------------------------------- */ int StaticCommunicatorMPI::getMinTag() { return 0; } /* -------------------------------------------------------------------------- */ // template // MPI_Datatype StaticCommunicatorMPI::getMPIDatatype() { // return MPI_DATATYPE_NULL; // } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_CHAR; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_FLOAT; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_DOUBLE; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_LONG_DOUBLE; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_INT; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_UNSIGNED; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_LONG; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_UNSIGNED_LONG; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_LONG_LONG; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype() { return MPI_UNSIGNED_LONG_LONG; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype >() { return MPI_DOUBLE_INT; } template <> MPI_Datatype MPITypeWrapper::getMPIDatatype >() { return MPI_FLOAT_INT; } /* -------------------------------------------------------------------------- */ /* Template instantiation */ /* -------------------------------------------------------------------------- */ #define AKANTU_MPI_COMM_INSTANTIATE(T) \ template void StaticCommunicatorMPI::send(T * buffer, Int size, \ Int receiver, Int tag); \ template void StaticCommunicatorMPI::receive(T * buffer, Int size, \ Int sender, Int tag); \ template CommunicationRequest * StaticCommunicatorMPI::asyncSend( \ T * buffer, Int size, Int receiver, Int tag); \ template CommunicationRequest * StaticCommunicatorMPI::asyncReceive( \ T * buffer, Int size, Int sender, Int tag); \ template void StaticCommunicatorMPI::probe(Int sender, Int tag, \ CommunicationStatus & status); \ template void StaticCommunicatorMPI::allGather(T * values, \ int nb_values); \ template void StaticCommunicatorMPI::allGatherV(T * values, \ int * nb_values); \ template void StaticCommunicatorMPI::gather(T * values, int nb_values, \ int root); \ template void StaticCommunicatorMPI::gatherV(T * values, int * nb_values, \ int root); \ template void StaticCommunicatorMPI::broadcast(T * values, int nb_values, \ int root); \ template void StaticCommunicatorMPI::allReduce( \ T * values, int nb_values, const SynchronizerOperation & op) AKANTU_MPI_COMM_INSTANTIATE(Real); AKANTU_MPI_COMM_INSTANTIATE(UInt); AKANTU_MPI_COMM_INSTANTIATE(Int); AKANTU_MPI_COMM_INSTANTIATE(char); template void StaticCommunicatorMPI::send >( SCMinMaxLoc * buffer, Int size, Int receiver, Int tag); template void StaticCommunicatorMPI::receive >( SCMinMaxLoc * buffer, Int size, Int sender, Int tag); template CommunicationRequest * StaticCommunicatorMPI::asyncSend >( SCMinMaxLoc * buffer, Int size, Int receiver, Int tag); template CommunicationRequest * StaticCommunicatorMPI::asyncReceive >( SCMinMaxLoc * buffer, Int size, Int sender, Int tag); template void StaticCommunicatorMPI::probe >( Int sender, Int tag, CommunicationStatus & status); template void StaticCommunicatorMPI::allGather >( SCMinMaxLoc * values, int nb_values); template void StaticCommunicatorMPI::allGatherV >( SCMinMaxLoc * values, int * nb_values); template void StaticCommunicatorMPI::gather >( SCMinMaxLoc * values, int nb_values, int root); template void StaticCommunicatorMPI::gatherV >( SCMinMaxLoc * values, int * nb_values, int root); template void StaticCommunicatorMPI::broadcast >( SCMinMaxLoc * values, int nb_values, int root); template void StaticCommunicatorMPI::allReduce >( SCMinMaxLoc * values, int nb_values, const SynchronizerOperation & op); #if AKANTU_INTEGER_SIZE > 4 AKANTU_MPI_COMM_INSTANTIATE(int); #endif __END_AKANTU__ diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.cc index 747906a85..746800751 100644 --- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.cc +++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.cc @@ -1,79 +1,79 @@ /** * @file test_material_elasto_plastic_linear_isotropic_hardening.cc * * @author Jaehyun Cho * @author Lucas Frerot * * @date creation: Thu Dec 03 2015 * * @brief test for material type elasto plastic linear isotropic hardening using * tension-compression test * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model.hh" #include /* -------------------------------------------------------------------------- */ using namespace akantu; /* -------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { initialize("test_material_elasto_plastic_linear_isotropic_hardening.dat", argc, argv); const UInt spatial_dimension = 2; const Real u_increment = 0.1; const UInt steps = 20; Mesh mesh(spatial_dimension); mesh.read("test_material_elasto_plastic_linear_isotropic_hardening.msh"); mesh.createGroupsFromMeshData("physical_names"); SolidMechanicsModel model(mesh); model.initFull(SolidMechanicsModelOptions(_static)); model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "left"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "bottom"); for (UInt i = 0 ; i < steps ; ++i) { model.applyBC(BC::Dirichlet::FixedValue(i * u_increment, _x), "right"); - model.solveStatic<_scm_newton_raphson_tangent, _scc_increment>(1e-12, 100); + model.solveStatic<_scm_newton_raphson_tangent, _scc_increment>(1e-6, 300); model.updateResidual(); Real strainxx = i * u_increment / 10.; const Array & edge_nodes = mesh.getElementGroup("right").getNodes(); Array & residual = model.getResidual(); Real reaction = 0; for (UInt n = 0 ; n < edge_nodes.getSize() ; n++) { reaction -= residual(edge_nodes(n), 0); } std::cout << strainxx << "," << reaction << std::endl; } finalize(); return EXIT_SUCCESS; } diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_standard_linear_isotropic_hardening.verified b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_standard_linear_isotropic_hardening.verified index 862cd8498..8a417a86d 100644 --- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_standard_linear_isotropic_hardening.verified +++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_standard_linear_isotropic_hardening.verified @@ -1,20 +1,20 @@ 0,0 0.01,1 0.02,2 0.03,3 0.04,4 0.05,5 0.06,6 0.07,7 0.08,8 0.09,9 0.1,10 -0.11,10.9577 -0.12,11.0089 -0.13,11.0106 -0.14,11.0107 -0.15,11.0107 -0.16,11.0107 -0.17,11.0107 -0.18,11.0107 -0.19,11.0107 +0.11,10.9565 +0.12,10.9949 +0.13,10.9964 +0.14,10.9965 +0.15,10.9965 +0.16,10.9965 +0.17,10.9965 +0.18,10.9965 +0.19,10.9965 diff --git a/test/test_solver/test_petsc_matrix_profile_parallel.cc b/test/test_solver/test_petsc_matrix_profile_parallel.cc index 3e9a6f552..fa7bf0368 100644 --- a/test/test_solver/test_petsc_matrix_profile_parallel.cc +++ b/test/test_solver/test_petsc_matrix_profile_parallel.cc @@ -1,133 +1,135 @@ /** * @file test_petsc_matrix_profile_parallel.cc * * @author Aurelia Isabel Cuba Ramos * * @date creation: Mon Oct 13 2014 * @date last modification: Tue Apr 28 2015 * * @brief test the profile generation of the PETScMatrix class in parallel * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #include "static_communicator.hh" #include "aka_common.hh" #include "aka_csr.hh" #include "mesh.hh" #include "mesh_io.hh" #include "mesh_utils.hh" #include "distributed_synchronizer.hh" #include "petsc_matrix.hh" #include "fe_engine.hh" #include "dof_synchronizer.hh" /// #include "dumper_paraview.hh" #include "mesh_partition_scotch.hh" using namespace akantu; int main(int argc, char *argv[]) { initialize(argc, argv); const ElementType element_type = _triangle_3; const GhostType ghost_type = _not_ghost; UInt spatial_dimension = 2; StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator(); Int psize = comm.getNbProc(); Int prank = comm.whoAmI(); /// read the mesh and partition it Mesh mesh(spatial_dimension); /* ------------------------------------------------------------------------ */ /* Parallel initialization */ /* ------------------------------------------------------------------------ */ DistributedSynchronizer * communicator = NULL; if(prank == 0) { /// creation mesh mesh.read("square.msh"); MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension); partition->partitionate(psize); communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition); delete partition; } else { communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL); } // dump mesh in paraview // DumperParaview mesh_dumper("mesh_dumper"); // mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost); // mesh_dumper.dump(); /// initialize the FEEngine and the dof_synchronizer FEEngine *fem = new FEEngineTemplate(mesh, spatial_dimension, "my_fem"); DOFSynchronizer dof_synchronizer(mesh, spatial_dimension); UInt nb_global_nodes = mesh.getNbGlobalNodes(); dof_synchronizer.initGlobalDOFEquationNumbers(); // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh UInt nb_element = mesh.getNbElement(element_type); UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type); UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element; SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric); K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension); /// use as elemental matrices a matrix with values equal to 1 every where Matrix element_input(nb_dofs_per_element, nb_dofs_per_element, 1.); Array K_e = Array(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e"); Array::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element); Array::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element); for(; K_e_it != K_e_end; ++K_e_it) *K_e_it = element_input; // assemble the test matrix fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type); /// construct a PETSc matrix PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric); /// build the profile of the PETSc matrix for the mesh of this example K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension); /// add an Akantu sparse matrix to a PETSc sparse matrix K_petsc.add(K_akantu, 1); /// save the profile K_petsc.saveMatrix("profile_parallel.txt"); /// print the matrix to screen - std::ifstream profile; - profile.open("profile_parallel.txt"); - std::string current_line; - while(getline(profile, current_line)) - std::cout << current_line << std::endl; - profile.close(); + if(prank == 0) { + std::ifstream profile; + profile.open("profile_parallel.txt"); + std::string current_line; + while(getline(profile, current_line)) + std::cout << current_line << std::endl; + profile.close(); + } delete communicator; finalize(); return EXIT_SUCCESS; } diff --git a/test/test_solver/test_solver_petsc_parallel.sh b/test/test_solver/test_solver_petsc_parallel.sh old mode 100644 new mode 100755