diff --git a/CMakeLists.txt b/CMakeLists.txt index a65669c2a..f476be652 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,190 +1,190 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date creation: Mon Jun 14 2010 # @date last modification: Fri Jan 22 2016 # # @brief main configuration file # # @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 <http://www.gnu.org/licenses/>. # # @section DESCRIPTION #------------------------------------------------------------------------------- # _ _ # | | | | # __ _| | ____ _ _ __ | |_ _ _ # / _` | |/ / _` | '_ \| __| | | | # | (_| | < (_| | | | | |_| |_| | # \__,_|_|\_\__,_|_| |_|\__|\__,_| # #=============================================================================== #=============================================================================== # CMake Project #=============================================================================== cmake_minimum_required(VERSION 3.1.3) # add this options before PROJECT keyword set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) project(Akantu) enable_language(CXX) #=============================================================================== # Misc. config for cmake #=============================================================================== set(AKANTU_CMAKE_DIR "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules") set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries.") mark_as_advanced(BUILD_SHARED_LIBS) if(NOT AKANTU_TARGETS_EXPORT) set(AKANTU_TARGETS_EXPORT AkantuTargets) endif() include(CMakeVersionGenerator) include(CMakePackagesSystem) include(CMakeFlagsHandling) include(AkantuPackagesSystem) include(AkantuMacros) include(AkantuCleaning) #cmake_activate_debug_message() #=============================================================================== # Version Number #=============================================================================== # AKANTU version number. An even minor number corresponds to releases. set(AKANTU_MAJOR_VERSION 3) set(AKANTU_MINOR_VERSION 0) set(AKANTU_PATCH_VERSION 0) define_project_version() #=============================================================================== # Options #=============================================================================== # Debug set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DAKANTU_NDEBUG" CACHE STRING "Flags used by the compiler during release builds" FORCE) #add_flags(cxx "-Wall -Wextra -pedantic -Werror") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") add_flags(cxx "-Wall -Wextra -pedantic") # -Weffc++ else() add_flags(cxx "-Wall") endif() option(AKANTU_EXAMPLES "Activate examples" OFF) option(AKANTU_TESTS "Activate tests" OFF) set(AKANTU_PREFERRED_PYTHON_VERSION 3 CACHE STRING "Preferred version for python related things") -mark_as_advanced(AKANTU_PREFERED_PYTHON_VERSION) +mark_as_advanced(AKANTU_PREFERRED_PYTHON_VERSION) include(AkantuExtraCompilationProfiles) #=============================================================================== # Dependencies #=============================================================================== declare_akantu_types() package_list_packages(${PROJECT_SOURCE_DIR}/packages EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages NO_AUTO_COMPILE_FLAGS) ## meta option \todo better way to do it when multiple package give enable the ## same feature if(AKANTU_SCOTCH) set(AKANTU_PARTITIONER ON) else() set(AKANTU_PARTITIONER OFF) endif() if(AKANTU_MUMPS) set(AKANTU_SOLVER ON) else() set(AKANTU_SOLVER OFF) endif() #=============================================================================== # Akantu library #=============================================================================== add_subdirectory(src) #=============================================================================== # Documentation #=============================================================================== if(AKANTU_DOCUMENTATION_DOXYGEN OR AKANTU_DOCUMENTATION_MANUAL) add_subdirectory(doc) else() set(AKANTU_DOC_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/doc/manual" CACHE INTERNAL "") endif() #=============================================================================== # Examples and tests #=============================================================================== include(AkantuTestsMacros) include(AkantuExampleMacros) if(AKANTU_TESTS) option(AKANTU_BUILD_ALL_TESTS "Build all tests" ON) find_package(GMSH REQUIRED) # package_is_activated(pybind11 _pybind11_act) # if(_pybind11_act) # find_package(pybind11 CONFIG REQUIRED QUIET) # to get the pybind11_add_module macro # endif() endif() if(AKANTU_EXAMPLES) find_package(GMSH REQUIRED) add_subdirectory(examples) endif() # tests add_test_tree(test) #=============================================================================== # Python interface #=============================================================================== package_is_activated(python_interface _python_act) if(_python_act) if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") set(AKANTU_PYTHON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) else() set(AKANTU_PYTHON_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") endif() add_subdirectory(python) endif() #=============================================================================== # Install and Packaging #=============================================================================== include(AkantuInstall) option(AKANTU_DISABLE_CPACK "This option commands the generation of extra info for the \"make package\" target" ON) mark_as_advanced(AKANTU_DISABLE_CPACK) if(NOT AKANTU_DISABLE_CPACK) include(AkantuCPack) endif() diff --git a/cmake/AkantuTestsMacros.cmake b/cmake/AkantuTestsMacros.cmake index 93bc8dc61..0dc3e34e9 100644 --- a/cmake/AkantuTestsMacros.cmake +++ b/cmake/AkantuTestsMacros.cmake @@ -1,608 +1,608 @@ #=============================================================================== # @file AkantuTestsMacros.cmake # # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date creation: Fri Sep 03 2010 # @date last modification: Fri Jan 22 2016 # # @brief macros for tests # # @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 <http://www.gnu.org/licenses/>. # #=============================================================================== #[=======================================================================[.rst: AkantuTestsMacros ----------------- This modules provides the functions to helper to declare tests and folders containing tests in akantu .. command:: add_test_tree add_test_tree(<test_direcotry>) ``<test_directory>`` is the entry direcroty of the full structure of subfolders containing tests .. command:: add_akantu_test add_akantu_test(<dir> <desc>) This function add a subdirectory ``<dir>`` of tests that will be conditionnaly activable and will be visible only if the parent folder as been activated An option ``AKANTU_BUILD_TEST_<dir>`` will appear in ccmake with the description ``<desc>``. The compilation of all tests can be forced with the option ``AKANTU_BUILD_ALL_TESTS`` .. command:: register_test register_test(<test_name> SOURCES <sources>... PACKAGE <akantu_packages>... SCRIPT <scirpt> [FILES_TO_COPY <filenames>...] [DEPENDS <targets>...] [DIRECTORIES_TO_CREATE <directories>...] [COMPILE_OPTIONS <flags>...] [EXTRA_FILES <filnames>...] [LINK_LIBRARIES <libraries>...] [INCLUDE_DIRECTORIES <include>...] [UNSABLE] [PARALLEL] [PARALLEL_LEVEL <procs>...] ) This function defines a test ``<test_name>_run`` this test could be of different nature depending on the context. If Just sources are provided the test consist of running the executable generated. If a file ``<test_name>.sh`` is present the test will execute the script. And if a ``<test_name>.verified`` exists the output of the test will be compared to this reference file The options are: ``SOURCES <sources>...`` The list of source files to compile to generate the executable of the test ``PACKAGE <akantu_packages>...`` The list of package to which this test belongs. The test will be activable only of all the packages listed are activated ``SCRIPT <script>`` The script to execute instead of the executable ``FILES_TO_COPY <filenames>...`` List of files to copy from the source directory to the build directory ``DEPENDS <targets>...`` List of targets the test depends on, for example if a mesh as to be generated ``DIRECTORIES_TO_CREATE <directories>...`` Obsolete. This specifies a list of directories that have to be created in the build folder ``COMPILE_OPTIONS <flags>...`` List of extra compilations options to pass to the compiler ``EXTRA_FILES <filnames>...`` Files to consider when generating a package_source ``UNSABLE`` If this option is specified the test can be unacitivated by the glocal option ``AKANTU_BUILD_UNSTABLE_TESTS``, this is mainly intendeed to remove test under developement from the continious integration ``PARALLEL`` This specifies that this test should be run in parallel. It will generate a series of test for different number of processors. This automaticaly adds a dependency to the package ``AKANTU_PARALLEL`` ``PARALLEL_LEVEL`` This defines the different processor numbers to use, if not defined the macro tries to determine it in a "clever" way ]=======================================================================] set(AKANTU_DRIVER_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_test_driver.sh) # ============================================================================== macro(add_test_tree dir) if(AKANTU_TESTS) enable_testing() include(CTest) mark_as_advanced(BUILD_TESTING) set(_akantu_current_parent_test ${dir} CACHE INTERNAL "Current test folder" FORCE) set(_akantu_${dir}_tests_count 0 CACHE INTERNAL "" FORCE) string(TOUPPER ${dir} _u_dir) set(AKANTU_BUILD_${_u_dir} ON CACHE INTERNAL "${desc}" FORCE) package_get_all_test_folders(_test_dirs) foreach(_dir ${_test_dirs}) add_subdirectory(${_dir}) endforeach() endif() endmacro() set(_test_flags UNSTABLE PARALLEL HEADER_ONLY ) set(_test_one_variables POSTPROCESS SCRIPT ) set(_test_multi_variables SOURCES FILES_TO_COPY DEPENDS DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES LINK_LIBRARIES INCLUDE_DIRECTORIES PACKAGE PARALLEL_LEVEL ) # ============================================================================== function(add_akantu_test dir desc) if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${dir}) return() endif() set(_my_parent_dir ${_akantu_current_parent_test}) # initialize variables set(_akantu_current_parent_test ${dir} CACHE INTERNAL "Current test folder" FORCE) set(_akantu_${dir}_tests_count 0 CACHE INTERNAL "" FORCE) # set the option for this directory string(TOUPPER ${dir} _u_dir) option(AKANTU_BUILD_${_u_dir} "${desc}") mark_as_advanced(AKANTU_BUILD_${_u_dir}) # add the sub-directory add_subdirectory(${dir}) # if no test can be activated make the option disappear set(_force_deactivate_count FALSE) if(${_akantu_${dir}_tests_count} EQUAL 0) set(_force_deactivate_count TRUE) endif() # if parent off make the option disappear set(_force_deactivate_parent FALSE) string(TOUPPER ${_my_parent_dir} _u_parent_dir) if(NOT AKANTU_BUILD_${_u_parent_dir}) set(_force_deactivate_parent TRUE) endif() if(_force_deactivate_parent OR _force_deactivate_count OR AKANTU_BUILD_ALL_TESTS) if(NOT DEFINED _AKANTU_BUILD_${_u_dir}_SAVE) set(_AKANTU_BUILD_${_u_dir}_SAVE ${AKANTU_BUILD_${_u_dir}} CACHE INTERNAL "" FORCE) endif() unset(AKANTU_BUILD_${_u_dir} CACHE) if(AKANTU_BUILD_ALL_TESTS AND NOT _force_deactivate_count) set(AKANTU_BUILD_${_u_dir} ON CACHE INTERNAL "${desc}" FORCE) else() set(AKANTU_BUILD_${_u_dir} OFF CACHE INTERNAL "${desc}" FORCE) endif() else() if(DEFINED _AKANTU_BUILD_${_u_dir}_SAVE) unset(AKANTU_BUILD_${_u_dir} CACHE) set(AKANTU_BUILD_${_u_dir} ${_AKANTU_BUILD_${_u_dir}_SAVE} CACHE BOOL "${desc}") unset(_AKANTU_BUILD_${_u_dir}_SAVE CACHE) endif() endif() # adding up to the parent count math(EXPR _tmp_parent_count "${_akantu_${dir}_tests_count} + ${_akantu_${_my_parent_dir}_tests_count}") set(_akantu_${_my_parent_dir}_tests_count ${_tmp_parent_count} CACHE INTERNAL "" FORCE) # restoring the parent current dir set(_akantu_current_parent_test ${_my_parent_dir} CACHE INTERNAL "Current test folder" FORCE) endfunction() function(is_test_active is_active) cmake_parse_arguments(_register_test "${_test_flags}" "${_test_one_variables}" "${_test_multi_variables}" ${ARGN} ) if(NOT _register_test_PACKAGE) message(FATAL_ERROR "No reference package was defined for the test" " ${test_name} in folder ${CMAKE_CURRENT_SOURCE_DIR}") endif() set(_test_act TRUE) # Activate the test anly if all packages associated to the test are activated foreach(_package ${_register_test_PACKAGE}) package_is_activated(${_package} _act) if(NOT _act) set(_test_act FALSE) endif() endforeach() # check if the test is marked unstable and if the unstable test should be run if(_register_test_UNSTABLE AND NOT AKANTU_BUILD_UNSTABLE_TESTS) set(_test_act FALSE) endif() if(_test_act) # todo this should be checked for the build package_sources since the file will not be listed. math(EXPR _tmp_parent_count "${_akantu_${_akantu_current_parent_test}_tests_count} + 1") set(_akantu_${_akantu_current_parent_test}_tests_count ${_tmp_parent_count} CACHE INTERNAL "" FORCE) endif() string(TOUPPER ${_akantu_current_parent_test} _u_parent) if(NOT (AKANTU_BUILD_${_u_parent} OR AKANTU_BUILD_ALL_TESTS)) set(_test_act FALSE) endif() set(${is_active} ${_test_act} PARENT_SCOPE) endfunction() # ------------------------------------------------------------------------------ function(register_gtest_sources) cmake_parse_arguments(_register_test "${_test_flags}" "${_test_one_variables}" "${_test_multi_variables}" ${ARGN} ) is_test_active(_is_active ${ARGN}) register_test_files_to_package(${ARGN}) if(NOT _is_active) return() endif() if(_register_test_PACKAGE) set(_list ${_gtest_PACKAGE}) list(APPEND _list ${_register_test_PACKAGE}) list(REMOVE_DUPLICATES _list) set(_gtest_PACKAGE ${_list} PARENT_SCOPE) endif() foreach (_var ${_test_flags}) if(_var STREQUAL "HEADER_ONLY") if(NOT DEFINED_register_test_${_var}) set(_gtest_${_var} OFF PARENT_SCOPE) elseif(NOT DEFINED _gtest_${_var}) set(_gtest_${_var} ON PARENT_SCOPE) endif() continue() endif() if(_register_test_${_var}) set(_gtest_${_var} ON PARENT_SCOPE) else() if(_gtest_${_var}) message("Another gtest file required ${_var} to be ON it will be globally set for this folder...") endif() endif() endforeach() if(_register_test_UNPARSED_ARGUMENTS) list(APPEND _register_test_SOURCES ${_register_test_UNPARSED_ARGUMENTS}) endif() foreach (_var ${_test_multi_variables}) if(_register_test_${_var}) set(_list ${_gtest_${_var}}) list(APPEND _list ${_register_test_${_var}}) list(REMOVE_DUPLICATES _list) set(_gtest_${_var} ${_list} PARENT_SCOPE) endif() endforeach() endfunction() # ============================================================================== function(akantu_pybind11_add_module target) package_is_activated(pybind11 _pybind11_act) if(_pybind11_act) package_get_all_external_informations( INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR ) pybind11_add_module(${target} ${ARGN}) target_include_directories(${target} SYSTEM PRIVATE ${PYBIND11_INCLUDE_DIR} ${AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR}) endif() endfunction() # ============================================================================== function(register_gtest_test test_name) if(NOT _gtest_PACKAGE) return() endif() set(_argn ${test_name}_gtest) set(_link_libraries GTest::GTest GTest::Main) list(FIND _gtest_PACKAGE pybind11 _pos) package_is_activated(pybind11 _pybind11_act) if(_pybind11_act AND (NOT _pos EQUAL -1)) list(APPEND _link_libraries pybind11::embed) set(_compile_flags COMPILE_OPTIONS "AKANTU_TEST_USE_PYBIND11") endif() is_test_active(_is_active ${ARGN} PACKAGE ${_gtest_PACKAGE}) if(NOT _is_active) return() endif() register_gtest_sources(${ARGN} SOURCES ${PROJECT_SOURCE_DIR}/test/test_gtest_main.cc LINK_LIBRARIES ${_link_libraries} PACKAGE ${_gtest_PACKAGE} ${_compile_flags} ) foreach (_var ${_test_flags}) if(_gtest_${_var}) list(APPEND _argn ${_var}) unset(_gtest_${_var}) endif() endforeach() foreach (_var ${_test_multi_variables}) if(_gtest_${_var}) list(APPEND _argn ${_var} ${_gtest_${_var}}) unset(_gtest_${_var}) endif() endforeach() register_test(${_argn}) target_include_directories(${test_name}_gtest PRIVATE ${PROJECT_SOURCE_DIR}/test) endfunction() # ============================================================================== function(register_test test_name) cmake_parse_arguments(_register_test "${_test_flags}" "${_test_one_variables}" "${_test_multi_variables}" ${ARGN} ) register_test_files_to_package(${ARGN}) is_test_active(_test_act ${ARGN}) if(NOT _test_act) return() endif() # check that the sources are files that need to be compiled if(_register_test_SOURCES} OR _register_test_UNPARSED_ARGUMENTS) set(_need_to_compile TRUE) else() set(_need_to_compile FALSE) endif() set(_compile_source) foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS}) if(_file MATCHES "\\.cc$" OR _file MATCHES "\\.hh$") list(APPEND _compile_source ${_file}) endif() endforeach() if(_compile_source) # get the include directories for sources in activated directories package_get_all_include_directories( AKANTU_LIBRARY_INCLUDE_DIRS ) # get the external packages compilation and linking informations package_get_all_external_informations( INTERFACE_INCLUDE AKANTU_EXTERNAL_INCLUDE_DIR ) foreach(_pkg ${_register_test_PACKAGE}) package_get_nature(${_pkg} _nature) if(_nature MATCHES "^external.*") package_get_include_dir(${_pkg} _incl) package_get_libraries(${_pkg} _libs) list(APPEND _register_test_INCLUDE_DIRECTORIES ${_incl}) list(APPEND _register_test_LINK_LIBRARIES ${_libs}) endif() endforeach() # Register the executable to compile add_executable(${test_name} ${_compile_source}) # set the proper includes to build most of the tests target_include_directories(${test_name} PRIVATE ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR} ${PROJECT_BINARY_DIR}/src ${_register_test_INCLUDE_DIRECTORIES}) if(NOT _register_test_HEADER_ONLY) target_link_libraries(${test_name} PRIVATE akantu ${_register_test_LINK_LIBRARIES}) else() get_target_property(_features akantu INTERFACE_COMPILE_FEATURES) target_link_libraries(${test_name} ${_register_test_LINK_LIBRARIES}) target_compile_features(${test_name} PRIVATE ${_features}) endif() if(_register_test_DEPENDS) add_dependencies(${test_name} ${_register_test_DEPENDS}) endif() # add the extra compilation options if(_register_test_COMPILE_OPTIONS) set_target_properties(${test_name} PROPERTIES COMPILE_DEFINITIONS "${_register_test_COMPILE_OPTIONS}") endif() if(AKANTU_EXTRA_CXX_FLAGS) set_target_properties(${test_name} PROPERTIES COMPILE_FLAGS "${AKANTU_EXTRA_CXX_FLAGS}") endif() else() if(_register_test_UNPARSED_ARGUMENTS AND NOT _register_test_SCRIPT) set(_register_test_SCRIPT ${_register_test_UNPARSED_ARGUMENTS}) endif() endif() # copy the needed files to the build folder if(_register_test_FILES_TO_COPY) foreach(_file ${_register_test_FILES_TO_COPY}) file(COPY "${_file}" DESTINATION .) endforeach() endif() # create the needed folders in the build folder if(_register_test_DIRECTORIES_TO_CREATE) foreach(_dir ${_register_test_DIRECTORIES_TO_CREATE}) if(IS_ABSOLUTE ${dir}) file(MAKE_DIRECTORY "${_dir}") else() file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_dir}") endif() endforeach() endif() # register the test for ctest set(_arguments -n "${test_name}") if(_register_test_SCRIPT) file(COPY ${_register_test_SCRIPT} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION .) list(APPEND _arguments -e "${_register_test_SCRIPT}") elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh") file(COPY ${test_name}.sh DESTINATION .) list(APPEND _arguments -e "${test_name}.sh") else() list(APPEND _arguments -e "${test_name}") endif() list(APPEND _arguments -E "${PROJECT_BINARY_DIR}/akantu_environement.sh") package_is_activated(parallel _is_parallel) if(_is_parallel AND AKANTU_TESTS_ALWAYS_USE_MPI AND NOT _register_test_PARALLEL) set(_register_test_PARALLEL TRUE) set(_register_test_PARALLEL_LEVEL 1) endif() if(_register_test_PARALLEL) - list(APPEND _arguments -p "${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG}") + list(APPEND _arguments -p "${MPIEXEC} ${MPIEXEC_PREFLAGS} ${MPIEXEC_NUMPROC_FLAG}") if(_register_test_PARALLEL_LEVEL) set(_procs "${_register_test_PARALLEL_LEVEL}") elseif(CMAKE_VERSION VERSION_GREATER "3.0") set(_procs) include(ProcessorCount) ProcessorCount(N) while(N GREATER 1) list(APPEND _procs ${N}) math(EXPR N "${N} / 2") endwhile() endif() if(NOT _procs) set(_procs 2) endif() endif() if(_register_test_POSTPROCESS) list(APPEND _arguments -s "${_register_test_POSTPROCESS}") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${_register_test_POSTPROCESS} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif() list(APPEND _arguments -w "${CMAKE_CURRENT_BINARY_DIR}") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified") list(APPEND _arguments -r "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified") endif() string(REPLACE ";" " " _command "${_arguments}") # register them test if(_procs) foreach(p ${_procs}) add_test(NAME ${test_name}_${p} COMMAND ${AKANTU_DRIVER_SCRIPT} ${_arguments} -N ${p}) endforeach() else() add_test(NAME ${test_name} COMMAND ${AKANTU_DRIVER_SCRIPT} ${_arguments}) endif() endfunction() function(register_test_files_to_package) set(_test_all_files) # add the source files in the list of all files foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS} ${_register_test_EXTRA_FILES} ${_register_test_SOURCES} ${_register_test_SCRIPT} ${_register_test_POSTPROCESS} ${_register_test_FILES_TO_COPY}) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_file} OR EXISTS ${_file}) list(APPEND _test_all_files "${_file}") else() message("The file \"${_file}\" registred by the test \"${test_name}\" does not exists") endif() endforeach() # add the different dependencies files (meshes, local libraries, ...) foreach(_dep ${_register_test_DEPENDS}) get_target_list_of_associated_files(${_dep} _dep_ressources) if(_dep_ressources) list(APPEND _test_all_files "${_dep_ressources}") endif() endforeach() # add extra files to the list of files referenced by a given test if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh") list(APPEND _test_all_files "${test_name}.sh") endif() if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified") list(APPEND _test_all_files "${test_name}.verified") endif() if(_register_test_SCRIPT) list(APPEND _test_all_files "${_register_test_SCRIPT}") endif() # clean the list of all files for this test and add them in the total list foreach(_file ${_test_all_files}) get_filename_component(_full ${_file} ABSOLUTE) file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_full}) list(APPEND _tmp "${__file}") endforeach() foreach(_pkg ${_register_test_PACKAGE}) package_get_name(${_pkg} _pkg_name) _package_add_to_variable(TESTS_FILES ${_pkg_name} ${_tmp}) endforeach() endfunction() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6105392e5..fbbf6db2c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,66 +1,67 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch> # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date creation: Fri Sep 03 2010 # @date last modification: Fri Jan 22 2016 # # @brief configuration for tests # # @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 <http://www.gnu.org/licenses/>. # # @section DESCRIPTION # #=============================================================================== include_directories( ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR} ) set(AKANTU_TESTS_FILES CACHE INTERNAL "") #=============================================================================== # List of tests #=============================================================================== add_akantu_test(test_common "Test the common part of Akantu") add_akantu_test(test_static_memory "Test static memory") add_akantu_test(test_fe_engine "Test finite element functionalties") add_akantu_test(test_mesh_utils "Test mesh utils") add_akantu_test(test_model "Test model objects") add_akantu_test(test_solver "Test solver function") add_akantu_test(test_io "Test the IO modules") add_akantu_test(test_contact "Test the contact part of Akantu") add_akantu_test(test_geometry "Test the geometry module of Akantu") add_akantu_test(test_synchronizer "Test synchronizers") add_akantu_test(test_python_interface "Test python interface") package_add_files_to_package( cmake/akantu_test_driver.sh cmake/AkantuTestsMacros.cmake ) package_is_activated(parallel _is_parallel) if (_is_parallel) option(AKANTU_TESTS_ALWAYS_USE_MPI "Defines if sequential tests should also use MPIEXEC" FALSE) + mark_as_advanced(AKANTU_TESTS_ALWAYS_USE_MPI) endif() diff --git a/test/test_fe_engine/test_fe_engine_gauss_integration.cc b/test/test_fe_engine/test_fe_engine_gauss_integration.cc index 2c27e0e27..9e44bc23e 100644 --- a/test/test_fe_engine/test_fe_engine_gauss_integration.cc +++ b/test/test_fe_engine/test_fe_engine_gauss_integration.cc @@ -1,153 +1,153 @@ /** * @file test_fe_engine_precomputation.cc * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Mon Jun 14 2010 * @date last modification: Mon Jul 13 2015 * * @brief test integration on elements, this test consider that mesh is a cube * * @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 <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "test_fe_engine_fixture.hh" /* -------------------------------------------------------------------------- */ #include <gtest/gtest.h> #include <iostream> /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { /* -------------------------------------------------------------------------- */ template <size_t t> using degree_t = std::integral_constant<size_t, t>; /* -------------------------------------------------------------------------- */ using TestDegreeTypes = std::tuple<degree_t<0>, degree_t<1>, degree_t<2>, degree_t<3>, degree_t<4>, degree_t<5>>; std::array<Polynomial<5>, 3> global_polys{ {{0.40062394, 0.13703225, 0.51731446, 0.87830084, 0.5410543, 0.71842292}, {0.41861835, 0.11080576, 0.49874043, 0.49077504, 0.85073835, 0.66259755}, {0.92620845, 0.7503478, 0.62962232, 0.31662719, 0.64069644, 0.30878135}}}; template <typename T> class TestGaussIntegrationFixture : public TestFEMFixture<std::tuple_element_t<0, T>> { protected: using parent = TestFEMFixture<std::tuple_element_t<0, T>>; - static constexpr size_t degree{std::tuple_element_t<1, T>{}}; + static constexpr size_t degree{std::tuple_element_t<1, T>::value}; public: TestGaussIntegrationFixture() : integration_points_pos(0, parent::dim) {} void SetUp() override { parent::SetUp(); auto integration_points = this->fem->getIntegrator().template getIntegrationPoints < parent::type, degree == 0 ? 1 : degree > (); nb_integration_points = integration_points.cols(); auto shapes_size = ElementClass<parent::type>::getShapeSize(); Array<Real> shapes(0, shapes_size); this->fem->getShapeFunctions() .template computeShapesOnIntegrationPoints<parent::type>( this->mesh->getNodes(), integration_points, shapes, _not_ghost); auto vect_size = this->nb_integration_points * this->nb_element; integration_points_pos.resize(vect_size); this->fem->getShapeFunctions() .template interpolateOnIntegrationPoints<parent::type>( this->mesh->getNodes(), integration_points_pos, this->dim, shapes); for (size_t d = 0; d < this->dim; ++d) { polys[d] = global_polys[d].extract(degree); } } void testIntegrate() { std::stringstream sstr; sstr << this->type << ":" << this->degree; SCOPED_TRACE(sstr.str().c_str()); auto vect_size = this->nb_integration_points * this->nb_element; Array<Real> polynomial(vect_size); size_t dim = parent::dim; for (size_t d = 0; d < dim; ++d) { auto poly = this->polys[d]; for (auto && pair : zip(polynomial, make_view(this->integration_points_pos, dim))) { auto && p = std::get<0>(pair); auto & x = std::get<1>(pair); p = poly(x(d)); } auto res = this->fem->getIntegrator() .template integrate<parent::type, (degree == 0 ? 1 : degree)>(polynomial); auto expect = poly.integrate(this->lower(d), this->upper(d)); for (size_t o = 0; o < dim; ++o) { if (o == d) continue; expect *= this->upper(d) - this->lower(d); } EXPECT_NEAR(expect, res, 5e-14); } } protected: UInt nb_integration_points; std::array<Array<Real>, parent::dim> polynomial; Array<Real> integration_points_pos; std::array<Polynomial<5>, 3> polys; }; template <typename T> constexpr size_t TestGaussIntegrationFixture<T>::degree; /* -------------------------------------------------------------------------- */ /* Tests */ /* -------------------------------------------------------------------------- */ TYPED_TEST_CASE_P(TestGaussIntegrationFixture); TYPED_TEST_P(TestGaussIntegrationFixture, ArbitraryOrder) { this->testIntegrate(); } REGISTER_TYPED_TEST_CASE_P(TestGaussIntegrationFixture, ArbitraryOrder); using TestTypes = gtest_list_t<tuple_split_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>; INSTANTIATE_TYPED_TEST_CASE_P(Split1, TestGaussIntegrationFixture, TestTypes); using TestTypesTail = gtest_list_t<tuple_split_tail_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>; INSTANTIATE_TYPED_TEST_CASE_P(Split2, TestGaussIntegrationFixture, TestTypesTail); } diff --git a/test/test_model/test_solid_mechanics_model/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/CMakeLists.txt index 073c9926b..773540d68 100644 --- a/test/test_model/test_solid_mechanics_model/CMakeLists.txt +++ b/test/test_model/test_solid_mechanics_model/CMakeLists.txt @@ -1,313 +1,277 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # # @date creation: Fri Sep 03 2010 # @date last modification: Tue Jan 19 2016 # # @brief configuratio for SolidMechanicsModel tests # # @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 <http://www.gnu.org/licenses/>. # # @section DESCRIPTION # #=============================================================================== add_akantu_test(test_materials "test_materials") add_akantu_test(patch_tests "patch_tests") add_akantu_test(test_cohesive "cohesive_test") add_akantu_test(test_embedded_interface "test_embedded_interface") - +add_akantu_test(test_energies "test energies") #=============================================================================== + #merged in test_solid_mechanics_model_dynamics #add_mesh(test_solid_mechanics_model_square_mesh square.geo 2 1) #merged in test_solid_mechanics_model_dynamics #add_mesh(test_solid_mechanics_model_circle_mesh1 circle.geo 2 1 OUTPUT circle1.msh) #merged in test_solid_mechanics_model_dynamics #add_mesh(test_solid_mechanics_model_circle_mesh2 circle.geo 2 2 OUTPUT circle2.msh) #merged in test_solid_mechanics_model_dynamics #register_test(test_solid_mechanics_model_square # SOURCES test_solid_mechanics_model_square.cc # DEPENDS test_solid_mechanics_model_square_mesh # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # #register_test(test_solid_mechanics_model_circle_2 # SOURCES test_solid_mechanics_model_circle_2.cc # DEPENDS test_solid_mechanics_model_circle_mesh2 # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # #=============================================================================== #merged in test_solid_mechanics_model_dynamics #add_mesh(test_bar_traction_2d_mesh1 bar.geo 2 1 OUTPUT bar1.msh) #add_mesh(test_bar_traction_2d_mesh2 bar.geo 2 2 OUTPUT bar2.msh) #add_mesh(test_bar_traction_2d_mesh_structured1 bar_structured.geo 2 1 OUTPUT bar_structured1.msh) #register_test(test_solid_mechanics_model_bar_traction2d # SOURCES test_solid_mechanics_model_bar_traction2d.cc # DEPENDS test_bar_traction_2d_mesh1 test_bar_traction_2d_mesh2 # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # #register_test(test_solid_mechanics_model_bar_traction2d_structured # SOURCES test_solid_mechanics_model_bar_traction2d_structured.cc # DEPENDS test_bar_traction_2d_mesh_structured1 # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # #=============================================================================== #merged in test_solid_mechanics_model_dynamics #add_mesh(test_solid_mechanics_model_segment_mesh segment.geo 1 2) # #register_test(test_solid_mechanics_model_bar_traction2d_parallel # SOURCES test_solid_mechanics_model_bar_traction2d_parallel.cc # DEPENDS test_bar_traction_2d_mesh2 # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE parallel # ) # #register_test(test_solid_mechanics_model_segment_parallel # SOURCES test_solid_mechanics_model_segment_parallel.cc # DEPENDS test_solid_mechanics_model_segment_mesh # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE parallel # ) # #=============================================================================== #register_test(test_solid_mechanics_model_bar_traction2d_mass_not_lumped # SOURCES test_solid_mechanics_model_bar_traction2d_mass_not_lumped.cc # DEPENDS test_bar_traction_2d_mesh1 test_bar_traction_2d_mesh2 # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE implicit # ) #=============================================================================== # add_mesh(test_solid_mechanics_model_segment_mesh1 segment.geo 1 1 OUTPUT segment1.msh) # add_mesh(test_implicit_mesh1 square_implicit.geo 2 1 OUTPUT square_implicit1.msh) # add_mesh(test_implicit_mesh2 square_implicit.geo 2 2 OUTPUT square_implicit2.msh) # register_test(test_solid_mechanics_model_implicit_1d # SOURCES test_solid_mechanics_model_implicit_1d.cc # DEPENDS test_solid_mechanics_model_segment_mesh1 # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE implicit # ) # register_test(test_solid_mechanics_model_implicit_2d # SOURCES test_solid_mechanics_model_implicit_2d.cc # DEPENDS test_implicit_mesh1 test_implicit_mesh2 # FILES_TO_COPY material_implicit.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE implicit # ) #=============================================================================== #merged in test_solid_mechanics_model_dynamics #add_mesh(test_implicit_beam_2d_1 beam_2d.geo 2 1 OUTPUT beam_2d_lin.msh) #add_mesh(test_implicit_beam_2d_2 beam_2d.geo 2 2 OUTPUT beam_2d_quad.msh) #add_mesh(test_implicit_beam_3d_2 beam_3d.geo 3 2 OUTPUT beam_3d_quad.msh) #add_mesh(test_implicit_beam_3d_1 beam_3d.geo 3 1 OUTPUT beam_3d_lin.msh) #register_test(test_solid_mechanics_model_implicit_dynamic_2d # SOURCES test_solid_mechanics_model_implicit_dynamic_2d.cc # DEPENDS test_implicit_beam_2d_1 test_implicit_beam_2d_2 test_implicit_beam_3d_2 test_implicit_beam_3d_1 # FILES_TO_COPY material_implicit_dynamic.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE implicit # ) # #=============================================================================== # register_test(test_solid_mechanics_model_bar_traction2d_structured_pbc # SOURCES test_solid_mechanics_model_bar_traction2d_structured_pbc.cc # DEPENDS test_bar_traction_2d_mesh_structured1 # FILES_TO_COPY material.dat test_cst_energy.pl # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) #add_mesh(test_pbc_parallel_mesh square_structured.geo 2 1 OUTPUT square_structured.msh) #register_test(test_solid_mechanics_model_pbc_parallel # SOURCES test_solid_mechanics_model_pbc_parallel.cc # DEPENDS test_pbc_parallel_mesh # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE parallel # ) #=============================================================================== #add_mesh(test_cube3d_mesh1 cube.geo 3 1 OUTPUT cube1.msh) #add_mesh(test_cube3d_mesh2 cube.geo 3 2 OUTPUT cube2.msh) #add_mesh(test_cube3d_mesh_structured cube_structured.geo 3 1 OUTPUT cube_structured.msh) # #register_test(test_solid_mechanics_model_cube3d # SOURCES test_solid_mechanics_model_cube3d.cc # DEPENDS test_cube3d_mesh1 # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # #register_test(test_solid_mechanics_model_cube3d_tetra10 # SOURCES test_solid_mechanics_model_cube3d_tetra10.cc # DEPENDS test_cube3d_mesh2 # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) # # register_test(test_solid_mechanics_model_cube3d_pbc # SOURCES test_solid_mechanics_model_cube3d_pbc.cc # DEPENDS test_cube3d_mesh_structured # FILES_TO_COPY material.dat # DIRECTORIES_TO_CREATE paraview # PACKAGE core # ) #add_mesh(test_solid_mechanics_model_boundary_condition_mesh cube_physical_names.geo 3 1) # register_test(test_solid_mechanics_model_boundary_condition # SOURCES test_solid_mechanics_model_boundary_condition.cc # DEPENDS test_cube3d_mesh1 # FILES_TO_COPY material.dat # PACKAGE core # ) #=============================================================================== add_mesh(test_cube3d_two_mat_mesh cube_two_materials.geo 3 1) register_test(test_solid_mechanics_model_reassign_material SOURCES test_solid_mechanics_model_reassign_material.cc DEPENDS test_cube3d_two_mat_mesh FILES_TO_COPY two_materials.dat PACKAGE parallel PARALLEL ) #=============================================================================== register_test(test_solid_mechanics_model_material_eigenstrain SOURCES test_solid_mechanics_model_material_eigenstrain.cc FILES_TO_COPY cube_3d_tet_4.msh; material_elastic_plane_strain.dat - PACKAGE core + PACKAGE implicit ) #=============================================================================== register_test(test_material_selector SOURCES test_material_selector.cc FILES_TO_COPY material_selector.dat material_selector.msh PACKAGE core ) -#=============================================================================== -# Meshes -#=============================================================================== -set(_meshes) -package_get_variable(ET_ELEMENT_TYPES core _element_list) -foreach(_et ${_element_list}) - if(NOT _et STREQUAL _point_1) - list(APPEND _meshes patch_tests/data/${_et}.msh) - endif() -endforeach() - add_mesh(bar_segment_2 patch_tests/data/bar_segment.geo DIM 1 ORDER 1 OUTPUT bar_segment_2.msh) add_mesh(bar_segment_3 patch_tests/data/bar_segment.geo DIM 1 ORDER 2 OUTPUT bar_segment_3.msh) add_mesh(bar_triangle_3 patch_tests/data/bar_triangle.geo DIM 2 ORDER 1 OUTPUT bar_triangle_3.msh) add_mesh(bar_triangle_6 patch_tests/data/bar_triangle.geo DIM 2 ORDER 2 OUTPUT bar_triangle_6.msh) add_mesh(bar_quadrangle_4 patch_tests/data/bar_quadrangle.geo DIM 2 ORDER 1 OUTPUT bar_quadrangle_4.msh) add_mesh(bar_quadrangle_8 patch_tests/data/bar_quadrangle.geo DIM 2 ORDER 2 OUTPUT bar_quadrangle_8.msh) add_mesh(bar_tetrahedron_4 patch_tests/data/bar_tetrahedron.geo DIM 3 ORDER 1 OUTPUT bar_tetrahedron_4.msh) add_mesh(bar_tetrahedron_10 patch_tests/data/bar_tetrahedron.geo DIM 3 ORDER 2 OUTPUT bar_tetrahedron_10.msh) add_mesh(bar_hexahedron_8 patch_tests/data/bar_hexahedron.geo DIM 3 ORDER 1 OUTPUT bar_hexahedron_8.msh) add_mesh(bar_hexahedron_20 patch_tests/data/bar_hexahedron.geo DIM 3 ORDER 2 OUTPUT bar_hexahedron_20.msh) +add_mesh(bar_pentahedron_6 patch_tests/data/bar_pentahedron.geo + DIM 3 ORDER 1 OUTPUT bar_pentahedron_6.msh) +add_mesh(bar_pentahedron_15 patch_tests/data/bar_pentahedron.geo + DIM 3 ORDER 2 OUTPUT bar_pentahedron_15.msh) -#=============================================================================== -# Energy tests -#=============================================================================== -register_gtest_sources( - SOURCES test_solid_mechanics_model_linear_elastic_potential_energy.cc - FILES_TO_COPY test_solid_mechanics_model_linear_elastic_potential_energy_material.dat - PACKAGE core - ) - -register_gtest_sources( - SOURCES test_solid_mechanics_model_kinetic_energy.cc - FILES_TO_COPY test_solid_mechanics_model_kinetic_energy_material.dat - PACKAGE implicit - ) - -register_gtest_sources( - SOURCES test_solid_mechanics_model_work_quasistatic.cc - FILES_TO_COPY test_solid_mechanics_model_work_material.dat - PACKAGE core - ) - -register_gtest_sources( - SOURCES test_solid_mechanics_model_work_dynamics.cc - FILES_TO_COPY test_solid_mechanics_model_work_material.dat - PACKAGE core - ) - -register_gtest_test(test_solid_mechanics_model_energies - FILES_TO_COPY ${_meshes} - DEPENDS bar_segment_2 bar_segment_3 bar_triangle_3 bar_triangle_6 - bar_quadrangle_4 bar_quadrangle_8 bar_tetrahedron_4 - bar_tetrahedron_10 bar_hexahedron_8 bar_hexahedron_20 - ) #=============================================================================== # dynamics tests #=============================================================================== register_gtest_sources( SOURCES test_solid_mechanics_model_dynamics.cc FILES_TO_COPY test_solid_mechanics_model_dynamics_material.dat PACKAGE core ) register_gtest_test(test_solid_mechanics_model - DEPENDS bar_segment_2 bar_segment_3 bar_triangle_3 bar_triangle_6 - bar_quadrangle_4 bar_quadrangle_8 bar_tetrahedron_4 - bar_tetrahedron_10 bar_hexahedron_8 bar_hexahedron_20 + DEPENDS bar_segment_2 bar_segment_3 + bar_triangle_3 bar_triangle_6 + bar_quadrangle_4 bar_quadrangle_8 + bar_tetrahedron_4 bar_tetrahedron_10 + bar_hexahedron_8 bar_hexahedron_20 + bar_pentahedron_6 bar_pentahedron_15 ) diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo index 6ca6ce290..c1fc9c3c7 100644 --- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo +++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo @@ -1,76 +1,76 @@ h = .6; Point(1) = {0, 0, 0, h}; Point(2) = {10, 0, 0, h}; Point(3) = {0, 1., 0, h}; Point(4) = {10, 1., 0, h}; Point(5) = {0, 0, 1., h}; Point(6) = {10, 0, 1., h}; Point(7) = {0, 1., 1., h}; Point(8) = {10, 1., 1., h}; Mesh.SecondOrderIncomplete = 1;//+ Line(1) = {7, 8}; //+ Line(2) = {8, 6}; //+ Line(3) = {6, 5}; //+ Line(4) = {5, 7}; //+ Line(5) = {3, 7}; //+ Line(6) = {3, 1}; //+ Line(7) = {1, 5}; //+ Line(8) = {4, 2}; //+ Line(9) = {4, 8}; //+ Line(10) = {2, 6}; //+ Line(11) = {4, 3}; //+ Line(12) = {1, 2}; //+ Line Loop(1) = {2, -10, -8, 9}; //+ Plane Surface(1) = {1}; //+ Line Loop(2) = {7, 4, -5, 6}; //+ Plane Surface(2) = {2}; //+ Line Loop(3) = {12, 10, 3, -7}; //+ Plane Surface(3) = {3}; //+ Line Loop(4) = {3, 4, 1, 2}; //+ Plane Surface(4) = {4}; //+ Line Loop(5) = {1, -9, 11, 5}; //+ Plane Surface(5) = {5}; //+ Line Loop(6) = {11, 6, 12, -8}; //+ Plane Surface(6) = {6}; //+ Surface Loop(1) = {3, 6, 5, 4, 2, 1}; //+ Volume(1) = {1}; //+ Physical Surface("BC") = {1, 2, 3, 4, 5, 6}; Physical Volume("bulk") = {1}; Transfinite Surface "*"; Transfinite Volume "*"; Recombine Surface "*"; -Mesh.SecondOrderIncomplete = 1; \ No newline at end of file +Mesh.SecondOrderIncomplete = 1; diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_pentahedron.geo similarity index 92% copy from test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo copy to test/test_model/test_solid_mechanics_model/patch_tests/data/bar_pentahedron.geo index 6ca6ce290..c11ea81e2 100644 --- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo +++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_pentahedron.geo @@ -1,76 +1,74 @@ h = .6; Point(1) = {0, 0, 0, h}; Point(2) = {10, 0, 0, h}; Point(3) = {0, 1., 0, h}; Point(4) = {10, 1., 0, h}; Point(5) = {0, 0, 1., h}; Point(6) = {10, 0, 1., h}; Point(7) = {0, 1., 1., h}; Point(8) = {10, 1., 1., h}; - -Mesh.SecondOrderIncomplete = 1;//+ Line(1) = {7, 8}; //+ Line(2) = {8, 6}; //+ Line(3) = {6, 5}; //+ Line(4) = {5, 7}; //+ Line(5) = {3, 7}; //+ Line(6) = {3, 1}; //+ Line(7) = {1, 5}; //+ Line(8) = {4, 2}; //+ Line(9) = {4, 8}; //+ Line(10) = {2, 6}; //+ Line(11) = {4, 3}; //+ Line(12) = {1, 2}; //+ Line Loop(1) = {2, -10, -8, 9}; //+ Plane Surface(1) = {1}; //+ Line Loop(2) = {7, 4, -5, 6}; //+ Plane Surface(2) = {2}; //+ Line Loop(3) = {12, 10, 3, -7}; //+ Plane Surface(3) = {3}; //+ Line Loop(4) = {3, 4, 1, 2}; //+ Plane Surface(4) = {4}; //+ Line Loop(5) = {1, -9, 11, 5}; //+ Plane Surface(5) = {5}; //+ Line Loop(6) = {11, 6, 12, -8}; //+ Plane Surface(6) = {6}; //+ Surface Loop(1) = {3, 6, 5, 4, 2, 1}; //+ Volume(1) = {1}; //+ Physical Surface("BC") = {1, 2, 3, 4, 5, 6}; Physical Volume("bulk") = {1}; Transfinite Surface "*"; Transfinite Volume "*"; -Recombine Surface "*"; -Mesh.SecondOrderIncomplete = 1; \ No newline at end of file +Recombine Surface {3, 4, 5, 6}; +Mesh.SecondOrderIncomplete = 1; diff --git a/test/test_model/test_solid_mechanics_model/test_energies/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_energies/CMakeLists.txt new file mode 100644 index 000000000..76663614e --- /dev/null +++ b/test/test_model/test_solid_mechanics_model/test_energies/CMakeLists.txt @@ -0,0 +1,47 @@ +#=============================================================================== +# Meshes +#=============================================================================== +set(_meshes) +package_get_variable(ET_ELEMENT_TYPES core _element_list) +foreach(_et ${_element_list}) + if(NOT _et STREQUAL _point_1) + list(APPEND _meshes ../patch_tests/data/${_et}.msh) + endif() +endforeach() + +#=============================================================================== +# Energy tests +#=============================================================================== +register_gtest_sources( + SOURCES test_solid_mechanics_model_linear_elastic_potential_energy.cc + FILES_TO_COPY test_solid_mechanics_model_linear_elastic_potential_energy_material.dat + PACKAGE implicit + ) + +register_gtest_sources( + SOURCES test_solid_mechanics_model_kinetic_energy.cc + FILES_TO_COPY test_solid_mechanics_model_kinetic_energy_material.dat + PACKAGE implicit + ) + +register_gtest_sources( + SOURCES test_solid_mechanics_model_work_quasistatic.cc + FILES_TO_COPY test_solid_mechanics_model_work_material.dat + PACKAGE implicit + ) + +register_gtest_sources( + SOURCES test_solid_mechanics_model_work_dynamics.cc + FILES_TO_COPY test_solid_mechanics_model_work_material.dat + PACKAGE core + ) + +register_gtest_test(test_solid_mechanics_model_energies + FILES_TO_COPY ${_meshes} + DEPENDS bar_segment_2 bar_segment_3 + bar_triangle_3 bar_triangle_6 + bar_quadrangle_4 bar_quadrangle_8 + bar_tetrahedron_4 bar_tetrahedron_10 + bar_hexahedron_8 bar_hexahedron_20 + bar_pentahedron_6 bar_pentahedron_15 + ) diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_kinetic_energy.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc similarity index 100% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_kinetic_energy.cc rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_kinetic_energy_material.dat b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy_material.dat similarity index 100% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_kinetic_energy_material.dat rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy_material.dat diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_linear_elastic_potential_energy.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_linear_elastic_potential_energy.cc similarity index 98% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_linear_elastic_potential_energy.cc rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_linear_elastic_potential_energy.cc index a6d5110e1..fe06d8007 100644 --- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_linear_elastic_potential_energy.cc +++ b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_linear_elastic_potential_energy.cc @@ -1,91 +1,91 @@ /** * @file test_solid_mechanics_model_potential_energy.cc * * @author Tobias Brink <tobias.brink@epfl.ch> * * @date creation: Tue Nov 14 2017 * @date last modification: Tue Nov 14 2017 * * @brief test potential energy of the linear elasticity model * * @section description * * This test uses a linear elastic material with density = 1, Young's * modulus = 1, and Poisson's ratio = 0 and applies a linear * displacement from 0 to ε in x direction. The resulting potential * energy density should be 0.5*Y*ε² = ε²/2. Since the mesh always has * a volume of 1, the energy density equals the total energy. We test * 3 different strains. * * @section LICENSE * * Copyright (©) 2017 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 <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#include "test_solid_mechanics_model_fixture.hh" +#include "../test_solid_mechanics_model_fixture.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { TYPED_TEST(TestSMMFixture, LinearElasticPotentialEnergy) { const auto spatial_dimension = this->spatial_dimension; getStaticParser().parse("test_solid_mechanics_model_linear_elastic_" "potential_energy_material.dat"); this->model->initFull(_analysis_method = _static); auto & lower = this->mesh->getLowerBounds(); auto & upper = this->mesh->getUpperBounds(); auto length = upper(_x) - lower(_x); const auto & pos = this->mesh->getNodes(); auto & disp = this->model->getDisplacement(); auto & boun = this->model->getBlockedDOFs(); std::vector<Real> strains{0.0, 0.1, 0.2, 0.3}; for (auto && eps : strains) { /// boundary conditions for (auto && pair : zip(make_view(pos, spatial_dimension), make_view(disp, spatial_dimension), make_view(boun, spatial_dimension))) { auto & posv = std::get<0>(pair); auto & dispv = std::get<1>(pair); auto & bounv = std::get<2>(pair); auto reduced_x = (posv(_x) - lower(_x)) / length; dispv(_x) = reduced_x * eps; bounv(_x) = true; } /// "solve" a step (solution is imposed) this->model->solveStep(); /// compare energy to analytical solution const auto E_ref = 0.5 * eps * eps; auto E_pot = this->model->getEnergy("potential"); EXPECT_NEAR(E_ref, E_pot, 1e-8); } } } // namespace diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_linear_elastic_potential_energy_material.dat b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_linear_elastic_potential_energy_material.dat similarity index 100% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_linear_elastic_potential_energy_material.dat rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_linear_elastic_potential_energy_material.dat diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_dynamics.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_dynamics.cc similarity index 52% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_dynamics.cc rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_dynamics.cc index d05b1a58c..72690cadb 100644 --- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_dynamics.cc +++ b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_dynamics.cc @@ -1,154 +1,158 @@ /** * @file test_solid_mechanics_model_work_dynamics.cc * * @author Tobias Brink <tobias.brink@epfl.ch> * * @date creation: Tue Dec 15 2017 * @date last modification: Dec Nov 15 2017 * * @brief test work in dynamic simulations * * @section description * * Assuming that the kinetic energy and the potential energy of the * linear elastic material are bug free, the work in a dynamic * simulation must equal the change in internal energy (first law of * thermodynamics). Work in dynamics is an infinitesimal work Fds, * thus we need to integrate it and compare at the end. In this test, * we use one Dirichlet boundary condition (with u = 0.0, 0.01, and * -0.01) and one Neumann boundary condition for F on the opposite * side. Then we do a few steps to get reference energies for work and * internal energy. After more steps, the change in both work and * internal energy must be equal. * * @section LICENSE * * Copyright (©) 2017 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 <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#include "test_solid_mechanics_model_fixture.hh" +#include "../test_solid_mechanics_model_fixture.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { -void test_body(SolidMechanicsModel & model, Mesh & mesh, - AnalysisMethod analysis_method, UInt steps_needed) { - const auto spatial_dimension = model.getSpatialDimension(); - - getStaticParser().parse("test_solid_mechanics_model_" - "work_material.dat"); - - /// model initialization - model.initFull(_analysis_method = analysis_method); - model.assembleMassLumped(); - - /// Create a node group for Neumann BCs. - auto & apply_force_grp = mesh.createNodeGroup("apply_force"); - auto & fixed_grp = mesh.createNodeGroup("fixed"); - - const auto & pos = mesh.getNodes(); - auto & lower = mesh.getLowerBounds(); - auto & upper = mesh.getUpperBounds(); - - UInt i = 0; - for (auto && posv : make_view(pos, spatial_dimension)) { - if (posv(_x) > upper(_x) - 1e-6) { - apply_force_grp.add(i); - } else if (posv(_x) < lower(_x) + 1e-6) { - fixed_grp.add(i); +template <typename type_> +class TestSMMFixtureWorkDynamic : public TestSMMFixture<type_> { +public: + void SetUp() override { + this->mesh_file = "../bar" + aka::to_string(this->type) + ".msh"; + TestSMMFixture<type_>::SetUp(); + + getStaticParser().parse("test_solid_mechanics_model_" + "work_material.dat"); + + /// model initialization + this->model->initFull(); + + /// Create a node group for Neumann BCs. + auto & apply_force_grp = this->mesh->createNodeGroup("apply_force"); + auto & fixed_grp = this->mesh->createNodeGroup("fixed"); + + const auto & pos = this->mesh->getNodes(); + const auto & lower = this->mesh->getLowerBounds(); + const auto & upper = this->mesh->getUpperBounds(); + + UInt i = 0; + for (auto && posv : make_view(pos, this->spatial_dimension)) { + if (posv(_x) > upper(_x) - 1e-6) { + apply_force_grp.add(i); + } else if (posv(_x) < lower(_x) + 1e-6) { + fixed_grp.add(i); + } + ++i; } - ++i; - } - - mesh.createElementGroupFromNodeGroup("el_apply_force", - "apply_force", - spatial_dimension - 1); - mesh.createElementGroupFromNodeGroup("el_fixed", - "fixed", - spatial_dimension - 1); - /// set up timestep - auto time_step = model.getStableTimeStep() * 0.1; - model.setTimeStep(time_step); + this->mesh->createElementGroupFromNodeGroup("el_apply_force", "apply_force", + this->spatial_dimension - 1); + this->mesh->createElementGroupFromNodeGroup("el_fixed", "fixed", + this->spatial_dimension - 1); - /// Do the sim - std::vector<Real> displacements{0.00, 0.01, -0.01}; - for (auto && u : displacements) { - model.applyBC(BC::Dirichlet::FixedValue(u, _x), "el_fixed"); - - Vector<Real> surface_traction(spatial_dimension); + Vector<Real> surface_traction(this->spatial_dimension); surface_traction(_x) = 0.5; - if (spatial_dimension == 1) { //TODO: this is a hack to work - // around non-implemented - // BC::Neumann::FromTraction for 1D - auto & force = model.getForce(); - for (auto && pair : zip(make_view(pos, spatial_dimension), - make_view(force, spatial_dimension))) { + if (this->spatial_dimension == 1) { + // TODO: this is a hack to work + // around non-implemented + // BC::Neumann::FromTraction for 1D + auto & force = this->model->getForce(); + + for (auto && pair : zip(make_view(pos, this->spatial_dimension), + make_view(force, this->spatial_dimension))) { auto & posv = std::get<0>(pair); auto & forcev = std::get<1>(pair); if (posv(_x) > upper(_x) - 1e-6) { forcev(_x) = surface_traction(_x); } } } else { - model.applyBC(BC::Neumann::FromTraction(surface_traction), - "el_apply_force"); + this->model->applyBC(BC::Neumann::FromTraction(surface_traction), + "el_apply_force"); } + /// set up timestep + auto time_step = this->model->getStableTimeStep() * 0.1; + this->model->setTimeStep(time_step); + } +}; + +TYPED_TEST_CASE(TestSMMFixtureWorkDynamic, types); + +/* TODO: this is currently disabled for terrible results and performance +TYPED_TEST(TestSMMFixtureBar, WorkImplicit) { + test_body(*(this->model), *(this->mesh), _implicit_dynamic, 500); +} +*/ +// model.assembleMassLumped(); +TYPED_TEST(TestSMMFixtureWorkDynamic, WorkExplicit) { + /// Do the sim + std::vector<Real> displacements{0.00, 0.01, -0.01}; + + for (auto && u : displacements) { + this->model->applyBC(BC::Dirichlet::FixedValue(u, _x), "el_fixed"); + // First, "equilibrate" a bit to get a reference state of total // energy and work. This is needed when we have a Dirichlet with // finite displacement on one side. for (UInt i = 0; i < 25; ++i) { - model.solveStep(); + this->model->solveStep(); } // Again, work reported by Akantu is infinitesimal (dW) and we // need to integrate a while to get a decent value. - double Etot0 = model.getEnergy("potential") + model.getEnergy("kinetic"); + double Etot0 = + this->model->getEnergy("potential") + this->model->getEnergy("kinetic"); double W = 0.0; - for (UInt i = 0; i < steps_needed; ++i) { + for (UInt i = 0; i < 200; ++i) { /// Solve. - model.solveStep(); + this->model->solveStep(); - const auto dW = model.getEnergy("external work"); + const auto dW = this->model->getEnergy("external work"); W += dW; } // Finally check. - const auto Epot = model.getEnergy("potential"); - const auto Ekin = model.getEnergy("kinetic"); + const auto Epot = this->model->getEnergy("potential"); + const auto Ekin = this->model->getEnergy("kinetic"); - EXPECT_NEAR(W, Ekin + Epot - Etot0, 5e-2); // Sadly not very exact - // for such a coarse mesh. + EXPECT_NEAR(W, Ekin + Epot - Etot0, 5e-2); + // Sadly not very exact for such a coarse mesh. } } - -/* TODO: this is currently disabled for terrible results and performance -TYPED_TEST(TestSMMFixtureBar, WorkImplicit) { - test_body(*(this->model), *(this->mesh), _implicit_dynamic, 500); } -*/ - -TYPED_TEST(TestSMMFixtureBar, WorkExplicit) { - test_body(*(this->model), *(this->mesh), _explicit_lumped_mass, 200); -} - -} // namespace diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_material.dat b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_material.dat similarity index 100% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_material.dat rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_material.dat diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_quasistatic.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc similarity index 98% rename from test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_quasistatic.cc rename to test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc index f21ca6bc6..ff09faa67 100644 --- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_work_quasistatic.cc +++ b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc @@ -1,136 +1,136 @@ /** * @file test_solid_mechanics_model_work_quasistatic.cc * * @author Tobias Brink <tobias.brink@epfl.ch> * * @date creation: Tue Nov 29 2017 * @date last modification: Tue Nov 29 2017 * * @brief test work in quasistatic * * @section description * * Assuming that the potential energy of a linear elastic material * works correctly, the work in a static simulation must equal the * potential energy of the material. Since the work in static is an * infinitesimal work Fds, we need to integrate by increasing F from 0 * to F_final in steps. This test uses one Dirichlet boundary * condition (with u = 0.0, 0.1, and -0.1) and one Neumann boundary * condition for F on the opposite side. The final work must be the * same for all u. * * @section LICENSE * * Copyright (©) 2017 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 <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#include "test_solid_mechanics_model_fixture.hh" +#include "../test_solid_mechanics_model_fixture.hh" #include "mesh_utils.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { TYPED_TEST(TestSMMFixture, WorkQuasistatic) { const auto spatial_dimension = this->spatial_dimension; getStaticParser().parse("test_solid_mechanics_model_" "work_material.dat"); /// model initialization MeshUtils::buildFacets(*this->mesh); this->model->initFull(_analysis_method = _static); /// Create a node group for Neumann BCs. auto & apply_force_grp = this->mesh->createNodeGroup("apply_force"); auto & fixed_grp = this->mesh->createNodeGroup("fixed"); const auto & pos = this->mesh->getNodes(); auto & lower = this->mesh->getLowerBounds(); auto & upper = this->mesh->getUpperBounds(); UInt i = 0; for (auto && posv : make_view(pos, spatial_dimension)) { if (posv(_x) > upper(_x) - 1e-6) { apply_force_grp.add(i); } else if (posv(_x) < lower(_x) + 1e-6) { fixed_grp.add(i); } ++i; } this->mesh->createElementGroupFromNodeGroup("el_apply_force", "apply_force", spatial_dimension - 1); this->mesh->createElementGroupFromNodeGroup("el_fixed", "fixed", spatial_dimension - 1); std::vector<Real> displacements{0.0, 0.1, -0.1}; for (auto && u : displacements) { this->model->applyBC(BC::Dirichlet::FixedValue(u, _x), "el_fixed"); Vector<Real> surface_traction(spatial_dimension); Real work = 0.0; Real Epot; static const UInt N = 100; for (UInt i = 0; i <= N; ++i) { this->model->getForce().clear(); // reset external forces to zero surface_traction(_x) = (1.0 * i) / N; if (spatial_dimension == 1) { //TODO: this is a hack to work // around non-implemented // BC::Neumann::FromTraction for 1D auto & force = this->model->getForce(); for (auto && pair : zip(make_view(pos, spatial_dimension), make_view(force, spatial_dimension))) { auto & posv = std::get<0>(pair); auto & forcev = std::get<1>(pair); if (posv(_x) > upper(_x) - 1e-6) { forcev(_x) = surface_traction(_x); } } } else { this->model->applyBC(BC::Neumann::FromTraction(surface_traction), "el_apply_force"); } /// Solve. this->model->solveStep(); Epot = this->model->getEnergy("potential"); // In static, this is infinitesimal work! auto Fds = this->model->getEnergy("external work"); work += Fds; // integrate /// Check that no work was done for zero force. if (i == 0) { EXPECT_NEAR(work, 0.0, 1e-12); } } // Due to the finite integration steps, we make a rather large error // in our work integration, thus the allowed delta is 1e-2. EXPECT_NEAR(work, Epot, 1e-2); } } } // namespace diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh index 430adc4e7..beef6ad66 100644 --- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh +++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh @@ -1,82 +1,63 @@ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model.hh" #include "test_gtest_utils.hh" /* -------------------------------------------------------------------------- */ #include <gtest/gtest.h> #include <vector> /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__ #define __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__ using namespace akantu; // This fixture uses very small meshes with a volume of 1. template <typename type_> class TestSMMFixture : public ::testing::Test { public: static constexpr ElementType type = type_::value; static constexpr size_t spatial_dimension = ElementClass<type>::getSpatialDimension(); void SetUp() override { mesh = std::make_unique<Mesh>(this->spatial_dimension); - mesh->read(this->makeMeshName()); + mesh->read(this->mesh_file); - std::stringstream element_type; - element_type << type; + SCOPED_TRACE(aka::to_string(this->type).c_str()); model = std::make_unique<SolidMechanicsModel>(*mesh, _all_dimensions, - element_type.str()); - } - - virtual std::string makeMeshName() { - std::stringstream element_type; - element_type << type; - SCOPED_TRACE(element_type.str().c_str()); - return element_type.str() + ".msh"; + aka::to_string(this->type)); } void TearDown() override { model.reset(nullptr); mesh.reset(nullptr); } protected: + std::string mesh_file{aka::to_string(this->type) + ".msh"}; std::unique_ptr<Mesh> mesh; std::unique_ptr<SolidMechanicsModel> model; }; template <typename type_> constexpr ElementType TestSMMFixture<type_>::type; template <typename type_> constexpr size_t TestSMMFixture<type_>::spatial_dimension; using types = gtest_list_t<TestElementTypes>; TYPED_TEST_CASE(TestSMMFixture, types); // This fixture uses somewhat finer meshes representing bars. template <typename type_> class TestSMMFixtureBar : public TestSMMFixture<type_> { public: void SetUp() override { - if (this->type == _pentahedron_6 || this->type == _pentahedron_15) - throw std::runtime_error("TODO pentahedron meshes for bar do not yet exist!"); - - std::cout << "testing type " << this->type << std::endl; - + this->mesh_file = "bar" + aka::to_string(this->type) + ".msh"; TestSMMFixture<type_>::SetUp(); } - - std::string makeMeshName() override { - std::stringstream element_type; - element_type << this->type; - SCOPED_TRACE(element_type.str().c_str()); - return std::string("bar") + element_type.str() + ".msh"; - } }; TYPED_TEST_CASE(TestSMMFixtureBar, types); - #endif /* __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__ */